From 2527424907a68e36bd5095c8b237e7e6682e0efb Mon Sep 17 00:00:00 2001 From: enitrat Date: Mon, 16 Jun 2025 18:27:57 +0200 Subject: [PATCH 01/12] feat: upgrade cairo version and use scarb binary in CLI --- .gitignore | 1 - Cargo.lock | 6168 ++--------------- Cargo.toml | 8 - README.md | 7 + Scarb.lock | 24 + corelib/Scarb.toml | 9 - corelib/cairo_project.toml | 9 - corelib/src/array.cairo | 270 - corelib/src/boolean.cairo | 19 - corelib/src/box.cairo | 34 - corelib/src/byte_array.cairo | 361 - corelib/src/bytes_31.cairo | 186 - corelib/src/clone.cairo | 10 - corelib/src/cmp.cairo | 44 - corelib/src/debug.cairo | 132 - corelib/src/dict.cairo | 105 - corelib/src/ec.cairo | 215 - corelib/src/ecdsa.cairo | 162 - corelib/src/felt_252.cairo | 31 - corelib/src/fmt.cairo | 204 - corelib/src/gas.cairo | 9 - corelib/src/hash.cairo | 150 - corelib/src/integer.cairo | 3046 -------- corelib/src/internal.cairo | 11 - corelib/src/keccak.cairo | 150 - corelib/src/lib.cairo | 369 - corelib/src/math.cairo | 160 - corelib/src/metaprogramming.cairo | 5 - corelib/src/nullable.cairo | 74 - corelib/src/num.cairo | 1 - corelib/src/num/traits.cairo | 12 - corelib/src/num/traits/bit_size.cairo | 6 - corelib/src/num/traits/one.cairo | 9 - corelib/src/num/traits/ops.cairo | 2 - corelib/src/num/traits/ops/overflowing.cairo | 23 - corelib/src/num/traits/ops/wrapping.cairo | 49 - corelib/src/num/traits/zero.cairo | 9 - corelib/src/option.cairo | 91 - corelib/src/panics.cairo | 19 - corelib/src/pedersen.cairo | 32 - corelib/src/poseidon.cairo | 87 - corelib/src/prelude.cairo | 2 - corelib/src/prelude/v2023_01.cairo | 70 - corelib/src/prelude/v2023_10.cairo | 27 - corelib/src/result.cairo | 84 - corelib/src/serde.cairo | 108 - corelib/src/starknet.cairo | 99 - corelib/src/starknet/account.cairo | 15 - corelib/src/starknet/class_hash.cairo | 65 - corelib/src/starknet/contract_address.cairo | 90 - corelib/src/starknet/eth_address.cairo | 69 - corelib/src/starknet/eth_signature.cairo | 59 - corelib/src/starknet/event.cairo | 8 - corelib/src/starknet/info.cairo | 133 - corelib/src/starknet/secp256_trait.cairo | 121 - corelib/src/starknet/secp256k1.cairo | 77 - corelib/src/starknet/secp256r1.cairo | 74 - corelib/src/starknet/storage.cairo | 71 - corelib/src/starknet/storage_access.cairo | 813 --- corelib/src/starknet/syscalls.cairo | 99 - corelib/src/starknet/testing.cairo | 92 - corelib/src/string.cairo | 1 - corelib/src/test.cairo | 28 - corelib/src/test/array_test.cairo | 154 - corelib/src/test/bool_test.cairo | 29 - corelib/src/test/box_test.cairo | 22 - corelib/src/test/byte_array_test.cairo | 568 -- corelib/src/test/bytes31_test.cairo | 192 - corelib/src/test/cmp_test.cairo | 299 - corelib/src/test/const_test.cairo | 134 - corelib/src/test/coupon_test.cairo | 26 - corelib/src/test/dict_test.cairo | 150 - corelib/src/test/ec_test.cairo | 159 - corelib/src/test/felt_test.cairo | 19 - corelib/src/test/fmt_test.cairo | 80 - corelib/src/test/hash_test.cairo | 89 - corelib/src/test/integer_test.cairo | 1950 ------ corelib/src/test/keccak_test.cairo | 201 - corelib/src/test/math_test.cairo | 123 - corelib/src/test/nullable_test.cairo | 31 - corelib/src/test/num_test.cairo | 237 - corelib/src/test/panics_test.cairo | 146 - corelib/src/test/plugins_test.cairo | 146 - corelib/src/test/print_test.cairo | 131 - corelib/src/test/result_test.cairo | 125 - corelib/src/test/secp256k1_test.cairo | 139 - corelib/src/test/secp256r1_test.cairo | 92 - corelib/src/test/test_utils.cairo | 29 - corelib/src/test/testing_test.cairo | 126 - corelib/src/test/to_byte_array_test.cairo | 249 - corelib/src/test/while_test.cairo | 27 - corelib/src/testing.cairo | 1 - corelib/src/to_byte_array.cairo | 129 - corelib/src/traits.cairo | 312 - corelib/src/zeroable.cairo | 84 - exercises/Scarb.lock | 24 + exercises/starknet/basics/starknet1.cairo | 13 +- exercises/starknet/basics/starknet2.cairo | 14 +- exercises/starknet/basics/starknet3.cairo | 25 +- exercises/starknet/basics/starknet4.cairo | 32 +- exercises/starknet/components/starknet6.cairo | 28 +- .../starknet/interoperability/starknet5.cairo | 40 +- .../.snfoundry_cache/.prev_tests_failed | 0 runner-crate/Scarb.lock | 20 +- runner-crate/Scarb.toml | 18 +- rust-toolchain | 4 + solutions/starknet/basics/starknet1.cairo | 41 + solutions/starknet/basics/starknet2.cairo | 58 + solutions/starknet/basics/starknet3.cairo | 120 + solutions/starknet/basics/starknet4.cairo | 158 + solutions/starknet/components/starknet6.cairo | 90 + .../starknet/interoperability/starknet5.cairo | 121 + src/exercise.rs | 35 +- src/lib.cairo | 10 + src/main.rs | 61 +- src/scarb.rs | 266 +- src/utils.rs | 2 +- tests/fixture/cairo/runner-crate/Scarb.lock | 20 +- tests/fixture/cairo/runner-crate/Scarb.toml | 20 +- tests/lib.cairo | 8 + 120 files changed, 1591 insertions(+), 20354 deletions(-) create mode 100644 Scarb.lock delete mode 100644 corelib/Scarb.toml delete mode 100644 corelib/cairo_project.toml delete mode 100644 corelib/src/array.cairo delete mode 100644 corelib/src/boolean.cairo delete mode 100644 corelib/src/box.cairo delete mode 100644 corelib/src/byte_array.cairo delete mode 100644 corelib/src/bytes_31.cairo delete mode 100644 corelib/src/clone.cairo delete mode 100644 corelib/src/cmp.cairo delete mode 100644 corelib/src/debug.cairo delete mode 100644 corelib/src/dict.cairo delete mode 100644 corelib/src/ec.cairo delete mode 100644 corelib/src/ecdsa.cairo delete mode 100644 corelib/src/felt_252.cairo delete mode 100644 corelib/src/fmt.cairo delete mode 100644 corelib/src/gas.cairo delete mode 100644 corelib/src/hash.cairo delete mode 100644 corelib/src/integer.cairo delete mode 100644 corelib/src/internal.cairo delete mode 100644 corelib/src/keccak.cairo delete mode 100644 corelib/src/lib.cairo delete mode 100644 corelib/src/math.cairo delete mode 100644 corelib/src/metaprogramming.cairo delete mode 100644 corelib/src/nullable.cairo delete mode 100644 corelib/src/num.cairo delete mode 100644 corelib/src/num/traits.cairo delete mode 100644 corelib/src/num/traits/bit_size.cairo delete mode 100644 corelib/src/num/traits/one.cairo delete mode 100644 corelib/src/num/traits/ops.cairo delete mode 100644 corelib/src/num/traits/ops/overflowing.cairo delete mode 100644 corelib/src/num/traits/ops/wrapping.cairo delete mode 100644 corelib/src/num/traits/zero.cairo delete mode 100644 corelib/src/option.cairo delete mode 100644 corelib/src/panics.cairo delete mode 100644 corelib/src/pedersen.cairo delete mode 100644 corelib/src/poseidon.cairo delete mode 100644 corelib/src/prelude.cairo delete mode 100644 corelib/src/prelude/v2023_01.cairo delete mode 100644 corelib/src/prelude/v2023_10.cairo delete mode 100644 corelib/src/result.cairo delete mode 100644 corelib/src/serde.cairo delete mode 100644 corelib/src/starknet.cairo delete mode 100644 corelib/src/starknet/account.cairo delete mode 100644 corelib/src/starknet/class_hash.cairo delete mode 100644 corelib/src/starknet/contract_address.cairo delete mode 100644 corelib/src/starknet/eth_address.cairo delete mode 100644 corelib/src/starknet/eth_signature.cairo delete mode 100644 corelib/src/starknet/event.cairo delete mode 100644 corelib/src/starknet/info.cairo delete mode 100644 corelib/src/starknet/secp256_trait.cairo delete mode 100644 corelib/src/starknet/secp256k1.cairo delete mode 100644 corelib/src/starknet/secp256r1.cairo delete mode 100644 corelib/src/starknet/storage.cairo delete mode 100644 corelib/src/starknet/storage_access.cairo delete mode 100644 corelib/src/starknet/syscalls.cairo delete mode 100644 corelib/src/starknet/testing.cairo delete mode 100644 corelib/src/string.cairo delete mode 100644 corelib/src/test.cairo delete mode 100644 corelib/src/test/array_test.cairo delete mode 100644 corelib/src/test/bool_test.cairo delete mode 100644 corelib/src/test/box_test.cairo delete mode 100644 corelib/src/test/byte_array_test.cairo delete mode 100644 corelib/src/test/bytes31_test.cairo delete mode 100644 corelib/src/test/cmp_test.cairo delete mode 100644 corelib/src/test/const_test.cairo delete mode 100644 corelib/src/test/coupon_test.cairo delete mode 100644 corelib/src/test/dict_test.cairo delete mode 100644 corelib/src/test/ec_test.cairo delete mode 100644 corelib/src/test/felt_test.cairo delete mode 100644 corelib/src/test/fmt_test.cairo delete mode 100644 corelib/src/test/hash_test.cairo delete mode 100644 corelib/src/test/integer_test.cairo delete mode 100644 corelib/src/test/keccak_test.cairo delete mode 100644 corelib/src/test/math_test.cairo delete mode 100644 corelib/src/test/nullable_test.cairo delete mode 100644 corelib/src/test/num_test.cairo delete mode 100644 corelib/src/test/panics_test.cairo delete mode 100644 corelib/src/test/plugins_test.cairo delete mode 100644 corelib/src/test/print_test.cairo delete mode 100644 corelib/src/test/result_test.cairo delete mode 100644 corelib/src/test/secp256k1_test.cairo delete mode 100644 corelib/src/test/secp256r1_test.cairo delete mode 100644 corelib/src/test/test_utils.cairo delete mode 100644 corelib/src/test/testing_test.cairo delete mode 100644 corelib/src/test/to_byte_array_test.cairo delete mode 100644 corelib/src/test/while_test.cairo delete mode 100644 corelib/src/testing.cairo delete mode 100644 corelib/src/to_byte_array.cairo delete mode 100644 corelib/src/traits.cairo delete mode 100644 corelib/src/zeroable.cairo create mode 100644 exercises/Scarb.lock create mode 100644 runner-crate/.snfoundry_cache/.prev_tests_failed create mode 100644 rust-toolchain create mode 100644 solutions/starknet/basics/starknet1.cairo create mode 100644 solutions/starknet/basics/starknet2.cairo create mode 100644 solutions/starknet/basics/starknet3.cairo create mode 100644 solutions/starknet/basics/starknet4.cairo create mode 100644 solutions/starknet/components/starknet6.cairo create mode 100644 solutions/starknet/interoperability/starknet5.cairo create mode 100644 src/lib.cairo create mode 100644 tests/lib.cairo diff --git a/.gitignore b/.gitignore index fcdd76343..5bdac39a9 100755 --- a/.gitignore +++ b/.gitignore @@ -11,5 +11,4 @@ rust-project.json !.vscode/extensions.json *.iml *.o -solutions/ **/runner-crate/src/lib.cairo diff --git a/Cargo.lock b/Cargo.lock index 35f41ad93..43ed80ab0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,51 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 - -[[package]] -name = "addr2line" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "adler2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" - -[[package]] -name = "aes" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" -dependencies = [ - "cfg-if 1.0.0", - "cipher", - "cpufeatures", -] - -[[package]] -name = "ahash" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" -dependencies = [ - "cfg-if 1.0.0", - "getrandom", - "once_cell", - "version_check", - "zerocopy", -] +version = 4 [[package]] name = "aho-corasick" @@ -56,32 +11,11 @@ dependencies = [ "memchr", ] -[[package]] -name = "alloc-no-stdlib" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" - -[[package]] -name = "alloc-stdlib" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" -dependencies = [ - "alloc-no-stdlib", -] - -[[package]] -name = "allocator-api2" -version = "0.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" - [[package]] name = "anstream" -version = "0.6.15" +version = "0.6.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" dependencies = [ "anstyle", "anstyle-parse", @@ -94,98 +28,77 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" [[package]] name = "anstyle-parse" -version = "0.2.5" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.1" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" dependencies = [ - "windows-sys 0.52.0", + "windows-sys", ] [[package]] name = "anstyle-wincon" -version = "3.0.4" +version = "3.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "once_cell_polyfill", + "windows-sys", ] [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" - -[[package]] -name = "arc-swap" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" [[package]] name = "argh" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7af5ba06967ff7214ce4c7419c7d185be7ecd6cc4965a8f6e1d8ce0398aad219" +checksum = "34ff18325c8a36b82f992e533ece1ec9f9a9db446bd1c14d4f936bac88fcd240" dependencies = [ "argh_derive", "argh_shared", + "rust-fuzzy-search", ] [[package]] name = "argh_derive" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56df0aeedf6b7a2fc67d06db35b09684c3e8da0c95f8f27685cb17e08413d87a" +checksum = "adb7b2b83a50d329d5d8ccc620f5c7064028828538bdf5646acd60dc1f767803" dependencies = [ "argh_shared", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.103", ] [[package]] name = "argh_shared" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5693f39141bda5760ecc4111ab08da40565d1771038c4a0250f03457ec707531" +checksum = "a464143cc82dedcdc3928737445362466b7674b5db4e2eb8e869846d6d84f4f6" dependencies = [ "serde", ] -[[package]] -name = "ark-ec" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" -dependencies = [ - "ark-ff", - "ark-poly", - "ark-serialize", - "ark-std 0.4.0", - "derivative", - "hashbrown 0.13.2", - "itertools 0.10.5", - "num-traits 0.2.19", - "zeroize", -] - [[package]] name = "ark-ff" version = "0.4.2" @@ -198,9 +111,9 @@ dependencies = [ "ark-std 0.4.0", "derivative", "digest", - "itertools 0.10.5", + "itertools", "num-bigint", - "num-traits 0.2.19", + "num-traits", "paste", "rustc_version", "zeroize", @@ -223,77 +136,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" dependencies = [ "num-bigint", - "num-traits 0.2.19", + "num-traits", "proc-macro2", "quote", "syn 1.0.109", ] -[[package]] -name = "ark-poly" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" -dependencies = [ - "ark-ff", - "ark-serialize", - "ark-std 0.4.0", - "derivative", - "hashbrown 0.13.2", -] - -[[package]] -name = "ark-secp256k1" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c02e954eaeb4ddb29613fee20840c2bbc85ca4396d53e33837e11905363c5f2" -dependencies = [ - "ark-ec", - "ark-ff", - "ark-std 0.4.0", -] - -[[package]] -name = "ark-secp256r1" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3975a01b0a6e3eae0f72ec7ca8598a6620fc72fa5981f6f5cca33b7cd788f633" -dependencies = [ - "ark-ec", - "ark-ff", - "ark-std 0.4.0", -] - [[package]] name = "ark-serialize" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" dependencies = [ - "ark-serialize-derive", "ark-std 0.4.0", "digest", "num-bigint", ] -[[package]] -name = "ark-serialize-derive" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "ark-std" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c" dependencies = [ - "num-traits 0.2.19", + "num-traits", "rand", ] @@ -303,25 +169,10 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" dependencies = [ - "num-traits 0.2.19", + "num-traits", "rand", ] -[[package]] -name = "arrayvec" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" - -[[package]] -name = "ascii-canvas" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8824ecca2e851cec16968d54a01dd372ef8f95b244fb84b84e70128be347c3c6" -dependencies = [ - "term", -] - [[package]] name = "assert_cmd" version = "0.11.1" @@ -335,5586 +186,1194 @@ dependencies = [ ] [[package]] -name = "assert_matches" -version = "1.5.0" +name = "autocfg" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] -name = "async-compression" -version = "0.4.12" +name = "bitflags" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fec134f64e2bc57411226dfc4e52dec859ddfc7e711fc5e07b612584f000e4aa" -dependencies = [ - "brotli", - "flate2", - "futures-core", - "memchr", - "pin-project-lite", - "tokio", -] +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] -name = "async-trait" -version = "0.1.82" +name = "bitflags" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a27b8a3a6e1a44fa4c8baf1f653e4172e81486d4941f2237e20dc2d0cf4ddff1" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" [[package]] -name = "autocfg" -version = "1.3.0" +name = "camino" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "0da45bc31171d8d6960122e222a67740df867c1dd53b4d51caa297084c185cab" [[package]] -name = "backtrace" -version = "0.3.73" +name = "cfg-if" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" -dependencies = [ - "addr2line", - "cc", - "cfg-if 1.0.0", - "libc", - "miniz_oxide 0.7.4", - "object", - "rustc-demangle", -] +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] -name = "base64" -version = "0.21.7" +name = "cfg-if" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] -name = "base64ct" -version = "1.6.0" +name = "clap" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f" +dependencies = [ + "clap_builder", + "clap_derive", +] [[package]] -name = "bincode" -version = "2.0.0-rc.3" +name = "clap_builder" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f11ea1a0346b94ef188834a65c068a03aec181c94896d481d7a0a40d85b0ce95" +checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e" dependencies = [ - "serde", + "anstream", + "anstyle", + "clap_lex", + "strsim", ] [[package]] -name = "bit-set" -version = "0.5.3" +name = "clap_derive" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce" dependencies = [ - "bit-vec", + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.103", ] [[package]] -name = "bit-vec" -version = "0.6.3" +name = "clap_lex" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" [[package]] -name = "bitflags" -version = "1.3.2" +name = "colorchoice" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" [[package]] -name = "bitflags" -version = "2.6.0" +name = "colored" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" +dependencies = [ + "lazy_static", + "windows-sys", +] [[package]] -name = "bitvec" -version = "1.0.1" +name = "console" +version = "0.15.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" dependencies = [ - "funty", - "radium", - "tap", - "wyz", + "encode_unicode", + "libc", + "once_cell", + "unicode-width", + "windows-sys", ] [[package]] -name = "block-buffer" -version = "0.10.4" +name = "crossbeam-deque" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ - "generic-array", + "crossbeam-epoch", + "crossbeam-utils", ] [[package]] -name = "brotli" -version = "6.0.0" +name = "crossbeam-epoch" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", - "brotli-decompressor", + "crossbeam-utils", ] [[package]] -name = "brotli-decompressor" -version = "4.0.1" +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crypto-common" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", + "generic-array", + "typenum", ] [[package]] -name = "bstr" -version = "1.10.0" +name = "dashmap" +version = "5.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ - "memchr", - "regex-automata 0.4.7", - "serde", + "cfg-if 1.0.1", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core 0.9.11", ] [[package]] -name = "bumpalo" -version = "3.16.0" +name = "derivative" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] [[package]] -name = "byte-slice-cast" -version = "1.2.2" +name = "difference" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" +checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" [[package]] -name = "byteorder" -version = "1.5.0" +name = "digest" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "crypto-common", +] [[package]] -name = "bytes" -version = "1.7.1" +name = "either" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] -name = "bytesize" -version = "1.3.0" +name = "encode_unicode" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e368af43e418a04d52505cf3dbc23dda4e3407ae2fa99fd0e4f308ce546acc" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] -name = "bzip2" -version = "0.4.4" +name = "escargot" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" +checksum = "ceb9adbf9874d5d028b5e4c5739d22b71988252b25c9c98fe7cf9738bee84597" dependencies = [ - "bzip2-sys", - "libc", + "lazy_static", + "log", + "serde", + "serde_json", ] [[package]] -name = "bzip2-sys" -version = "0.1.11+1.0.8" +name = "filetime" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" dependencies = [ - "cc", + "cfg-if 1.0.1", "libc", - "pkg-config", + "libredox", + "windows-sys", ] [[package]] -name = "cairo-lang-casm" -version = "2.8.2" +name = "float-cmp" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a4b4ca8473c25d1e760c83c2a49d953197556f82f6feb636004d3b6d6cc4a7" +checksum = "e1267f4ac4f343772758f7b1bdcbe767c218bbab93bb432acbf5162bbf85a6c4" dependencies = [ - "cairo-lang-utils", - "indoc", - "num-bigint", - "num-traits 0.2.19", - "parity-scale-codec", - "serde", + "num-traits", ] [[package]] -name = "cairo-lang-compiler" -version = "2.8.2" +name = "fsevent" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5852668d1c6966b34d6e4fe249732769ab9cb2012c201e3889d8119f206760a0" +checksum = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6" dependencies = [ - "anyhow", - "cairo-lang-defs", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-lowering", - "cairo-lang-parser", - "cairo-lang-project", - "cairo-lang-semantic", - "cairo-lang-sierra", - "cairo-lang-sierra-generator", - "cairo-lang-syntax", - "cairo-lang-utils", - "indoc", - "rayon 1.10.0", - "rust-analyzer-salsa", - "semver", - "smol_str", - "thiserror", + "bitflags 1.3.2", + "fsevent-sys", ] [[package]] -name = "cairo-lang-debug" -version = "2.8.2" +name = "fsevent-sys" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0644fab571f598547993936918c85f0e89b0bbc15140ca3ea723bff376be07d" +checksum = "f41b048a94555da0f42f1d632e2e19510084fb8e303b0daa2816e733fb3644a0" dependencies = [ - "cairo-lang-utils", + "libc", ] [[package]] -name = "cairo-lang-defs" -version = "2.8.2" +name = "fuchsia-zircon" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f5f437d75ac25644880458effde562edcac45a888d27f2e497d30c6450fa97d" +checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" dependencies = [ - "cairo-lang-debug", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-parser", - "cairo-lang-syntax", - "cairo-lang-utils", - "itertools 0.12.1", - "rust-analyzer-salsa", - "smol_str", + "bitflags 1.3.2", + "fuchsia-zircon-sys", ] [[package]] -name = "cairo-lang-diagnostics" -version = "2.8.2" +name = "fuchsia-zircon-sys" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ec5b44d3eaf50e28e068d163e56b9effcea6afe3625c32dd96418d2d4ebc34c" -dependencies = [ - "cairo-lang-debug", - "cairo-lang-filesystem", - "cairo-lang-utils", - "itertools 0.12.1", -] +checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" [[package]] -name = "cairo-lang-eq-solver" -version = "2.8.2" +name = "futures" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0cd844e568f51e39729e8ac18bd27ada2e2b6dc9138f8c81adad48456480681" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ - "cairo-lang-utils", - "good_lp", + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", ] [[package]] -name = "cairo-lang-filesystem" -version = "2.8.2" +name = "futures-channel" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "323a2385e000589f7591f8a46599b4a462db6e36e5935bad3bceddcc1a1608e1" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ - "cairo-lang-debug", - "cairo-lang-utils", - "path-clean", - "rust-analyzer-salsa", - "semver", - "serde", - "smol_str", -] - -[[package]] -name = "cairo-lang-formatter" -version = "2.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cf9cf637e12d41260dc59f3d988c76a6347424913ac8b6b8449ff3e79b59750" -dependencies = [ - "anyhow", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-parser", - "cairo-lang-syntax", - "cairo-lang-utils", - "diffy", - "ignore", - "itertools 0.12.1", - "rust-analyzer-salsa", - "serde", - "smol_str", - "thiserror", -] - -[[package]] -name = "cairo-lang-lowering" -version = "2.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d71bc5b1f19a00eb662c2cac33259b16b9cdbf9c005047aca0d538c13936407" -dependencies = [ - "cairo-lang-debug", - "cairo-lang-defs", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-parser", - "cairo-lang-proc-macros", - "cairo-lang-semantic", - "cairo-lang-syntax", - "cairo-lang-utils", - "id-arena", - "itertools 0.12.1", - "log", - "num-bigint", - "num-traits 0.2.19", - "rust-analyzer-salsa", - "smol_str", -] - -[[package]] -name = "cairo-lang-macro" -version = "0.1.0" -source = "git+https://github.com/software-mansion/scarb?tag=v2.8.2#a37b4cbfc9d7560e4d1375a3b1707c165aedd22a" -dependencies = [ - "cairo-lang-macro-attributes", - "cairo-lang-macro-stable", - "linkme", -] - -[[package]] -name = "cairo-lang-macro-attributes" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e32e958decd95ae122ee64daa26721da2f76e83231047f947fd9cdc5d3c90cc6" -dependencies = [ - "quote", - "scarb-stable-hash 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 2.0.77", -] - -[[package]] -name = "cairo-lang-macro-stable" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c49906d6b1c215e5814be7c5c65ecf2328898b335bee8c2409ec07cfb5530daf" - -[[package]] -name = "cairo-lang-parser" -version = "2.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d939d258e26ace0f3cb1e50338ae18981a7505e3c20eabd24a62d70ee862d6c" -dependencies = [ - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-syntax", - "cairo-lang-syntax-codegen", - "cairo-lang-utils", - "colored", - "itertools 0.12.1", - "num-bigint", - "num-traits 0.2.19", - "rust-analyzer-salsa", - "smol_str", - "unescaper", -] - -[[package]] -name = "cairo-lang-plugins" -version = "2.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67a553a6d2d2b54264e77e3c8cb5bc866b40b32d5e2144a58b74c559c7e289f" -dependencies = [ - "cairo-lang-defs", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-parser", - "cairo-lang-syntax", - "cairo-lang-utils", - "indent", - "indoc", - "itertools 0.12.1", - "rust-analyzer-salsa", - "smol_str", -] - -[[package]] -name = "cairo-lang-proc-macros" -version = "2.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c33b5f4502b7efde6ac07fd5468f6dae15d88760aeece3d57a7bc4c224ba693e" -dependencies = [ - "cairo-lang-debug", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "cairo-lang-project" -version = "2.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b63d6a3cc86a79a29978acaaf6f94738c5487e265247fe06c7bf359645d8c200" -dependencies = [ - "cairo-lang-filesystem", - "cairo-lang-utils", - "serde", - "smol_str", - "thiserror", - "toml 0.8.19", -] - -[[package]] -name = "cairo-lang-runner" -version = "2.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528a247ac59cb35b2f99d64605a81de815fa5fb0b0e7f7ece1d4e7fcf267d4ea" -dependencies = [ - "ark-ff", - "ark-secp256k1", - "ark-secp256r1", - "cairo-lang-casm", - "cairo-lang-lowering", - "cairo-lang-sierra", - "cairo-lang-sierra-ap-change", - "cairo-lang-sierra-generator", - "cairo-lang-sierra-to-casm", - "cairo-lang-sierra-type-size", - "cairo-lang-starknet", - "cairo-lang-utils", - "cairo-vm", - "itertools 0.12.1", - "keccak", - "num-bigint", - "num-integer", - "num-traits 0.2.19", - "rand", - "sha2", - "smol_str", - "starknet-types-core", - "thiserror", -] - -[[package]] -name = "cairo-lang-semantic" -version = "2.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00c284031fd14796dad91483c3039d7929f8440e1e9e334017744b1d22df5aa8" -dependencies = [ - "cairo-lang-debug", - "cairo-lang-defs", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-parser", - "cairo-lang-plugins", - "cairo-lang-proc-macros", - "cairo-lang-syntax", - "cairo-lang-test-utils", - "cairo-lang-utils", - "id-arena", - "indoc", - "itertools 0.12.1", - "num-bigint", - "num-traits 0.2.19", - "rust-analyzer-salsa", - "smol_str", - "toml 0.8.19", -] - -[[package]] -name = "cairo-lang-sierra" -version = "2.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891488c1a3184ce91679f5bdb63015a1d24769a48bd07e5d51a1779d0031dfbe" -dependencies = [ - "anyhow", - "cairo-lang-utils", - "const-fnv1a-hash", - "convert_case", - "derivative", - "itertools 0.12.1", - "lalrpop", - "lalrpop-util", - "num-bigint", - "num-integer", - "num-traits 0.2.19", - "regex", - "rust-analyzer-salsa", - "serde", - "serde_json", - "sha3", - "smol_str", - "starknet-types-core", - "thiserror", -] - -[[package]] -name = "cairo-lang-sierra-ap-change" -version = "2.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea7752cd48c86b2cde8603b753a6df4da086dacd16a73d288854d5f040b51171" -dependencies = [ - "cairo-lang-eq-solver", - "cairo-lang-sierra", - "cairo-lang-sierra-type-size", - "cairo-lang-utils", - "itertools 0.12.1", - "num-bigint", - "num-traits 0.2.19", - "thiserror", -] - -[[package]] -name = "cairo-lang-sierra-gas" -version = "2.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "340892a09c9421414b2ac45b03c705f16e2bd737e4559dfd98ee1d20718dec9e" -dependencies = [ - "cairo-lang-eq-solver", - "cairo-lang-sierra", - "cairo-lang-sierra-type-size", - "cairo-lang-utils", - "itertools 0.12.1", - "num-bigint", - "num-traits 0.2.19", - "thiserror", -] - -[[package]] -name = "cairo-lang-sierra-generator" -version = "2.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5cc616e8df44c4d685fe3c5f81f35ebbda57225098b35cea8602457c45c9e96" -dependencies = [ - "cairo-lang-debug", - "cairo-lang-defs", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-lowering", - "cairo-lang-parser", - "cairo-lang-semantic", - "cairo-lang-sierra", - "cairo-lang-syntax", - "cairo-lang-utils", - "itertools 0.12.1", - "num-traits 0.2.19", - "rust-analyzer-salsa", - "serde", - "serde_json", - "smol_str", -] - -[[package]] -name = "cairo-lang-sierra-to-casm" -version = "2.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c22ff7e8113a46a907f82f191096c96935cc48247e3079971ddf536ccc2f4f8" -dependencies = [ - "assert_matches", - "cairo-lang-casm", - "cairo-lang-sierra", - "cairo-lang-sierra-ap-change", - "cairo-lang-sierra-gas", - "cairo-lang-sierra-type-size", - "cairo-lang-utils", - "indoc", - "itertools 0.12.1", - "num-bigint", - "num-traits 0.2.19", - "starknet-types-core", - "thiserror", -] - -[[package]] -name = "cairo-lang-sierra-type-size" -version = "2.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf41941776e7410a8853a8e2a116292fc24d219df1989a92ffe5ab0e98037eb" -dependencies = [ - "cairo-lang-sierra", - "cairo-lang-utils", -] - -[[package]] -name = "cairo-lang-starknet" -version = "2.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5508fa5ee8d24adf7d2c65505d0ac35efc892eac16d1449c6f7e314a0288cb8" -dependencies = [ - "anyhow", - "cairo-lang-compiler", - "cairo-lang-defs", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-lowering", - "cairo-lang-plugins", - "cairo-lang-semantic", - "cairo-lang-sierra", - "cairo-lang-sierra-generator", - "cairo-lang-starknet-classes", - "cairo-lang-syntax", - "cairo-lang-utils", - "const_format", - "indent", - "indoc", - "itertools 0.12.1", - "serde", - "serde_json", - "smol_str", - "starknet-types-core", - "thiserror", -] - -[[package]] -name = "cairo-lang-starknet-classes" -version = "2.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "482b8f9d7f8cc7140f1260ee71f3308a66d15bd228a06281067ca3f8f4410db2" -dependencies = [ - "cairo-lang-casm", - "cairo-lang-sierra", - "cairo-lang-sierra-to-casm", - "cairo-lang-utils", - "convert_case", - "itertools 0.12.1", - "num-bigint", - "num-integer", - "num-traits 0.2.19", - "serde", - "serde_json", - "sha3", - "smol_str", - "starknet-types-core", - "thiserror", -] - -[[package]] -name = "cairo-lang-syntax" -version = "2.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7db0776c3d06cea65d7afe7a3c7685f6867eb6d951cf505caf35abfd1746773b" -dependencies = [ - "cairo-lang-debug", - "cairo-lang-filesystem", - "cairo-lang-utils", - "num-bigint", - "num-traits 0.2.19", - "rust-analyzer-salsa", - "smol_str", - "unescaper", -] - -[[package]] -name = "cairo-lang-syntax-codegen" -version = "2.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce0f7fa01c26cc731bc1d6350ac02fae91a68b5fdf60e684f991e861715adc4" -dependencies = [ - "genco", - "xshell", -] - -[[package]] -name = "cairo-lang-test-plugin" -version = "2.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74f1597b8229a3649183ff33b19f0aeca5d86505253ebbbce377b271d1732835" -dependencies = [ - "anyhow", - "cairo-lang-compiler", - "cairo-lang-debug", - "cairo-lang-defs", - "cairo-lang-filesystem", - "cairo-lang-lowering", - "cairo-lang-semantic", - "cairo-lang-sierra", - "cairo-lang-sierra-generator", - "cairo-lang-starknet", - "cairo-lang-starknet-classes", - "cairo-lang-syntax", - "cairo-lang-utils", - "indoc", - "itertools 0.12.1", - "num-bigint", - "num-traits 0.2.19", - "serde", - "starknet-types-core", -] - -[[package]] -name = "cairo-lang-test-runner" -version = "2.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "796770ad15d897d0a6d57d8c7832323e96204f172b1377ab30dcb7c28a75e2fc" -dependencies = [ - "anyhow", - "cairo-lang-compiler", - "cairo-lang-filesystem", - "cairo-lang-runner", - "cairo-lang-sierra", - "cairo-lang-sierra-generator", - "cairo-lang-sierra-to-casm", - "cairo-lang-starknet", - "cairo-lang-test-plugin", - "cairo-lang-utils", - "colored", - "itertools 0.12.1", - "num-traits 0.2.19", - "rayon 1.10.0", - "starknet-types-core", -] - -[[package]] -name = "cairo-lang-test-utils" -version = "2.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630a070a69c387eee9c0eda65e4f2508d129d4fbe081091077e661020ab95637" -dependencies = [ - "cairo-lang-formatter", - "cairo-lang-utils", - "colored", - "log", - "pretty_assertions", -] - -[[package]] -name = "cairo-lang-utils" -version = "2.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73104609a7d865e4cd1de9cbf4e750683d076b6d0233bf81be511df274a26916" -dependencies = [ - "env_logger", - "hashbrown 0.14.5", - "indexmap 2.5.0", - "itertools 0.12.1", - "log", - "num-bigint", - "num-traits 0.2.19", - "schemars", - "serde", - "time", -] - -[[package]] -name = "cairo-vm" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58363ad8065ed891e3b14a8191b707677c7c7cb5b9d10030822506786d8d8108" -dependencies = [ - "anyhow", - "bincode", - "bitvec", - "generic-array", - "hashbrown 0.14.5", - "hex", - "keccak", - "lazy_static", - "nom", - "num-bigint", - "num-integer", - "num-prime", - "num-traits 0.2.19", - "rand", - "rust_decimal", - "serde", - "serde_json", - "sha2", - "sha3", - "starknet-crypto", - "starknet-types-core", - "thiserror-no-std", - "zip", -] - -[[package]] -name = "camino" -version = "1.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" -dependencies = [ - "serde", -] - -[[package]] -name = "cargo-platform" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" -dependencies = [ - "serde", -] - -[[package]] -name = "cargo_metadata" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" -dependencies = [ - "camino", - "cargo-platform", - "semver", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "cc" -version = "1.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9d013ecb737093c0e86b151a7b837993cf9ec6c502946cfb44bedc392421e0b" -dependencies = [ - "jobserver", - "libc", - "shlex", -] - -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common", - "inout", -] - -[[package]] -name = "clap" -version = "4.5.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.5.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.5.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" -dependencies = [ - "heck 0.5.0", - "proc-macro2", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "clap_lex" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" - -[[package]] -name = "clru" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbd0f76e066e64fdc5631e3bb46381254deab9ef1158292f27c8c57e3bf3fe59" - -[[package]] -name = "colorchoice" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" - -[[package]] -name = "colored" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" -dependencies = [ - "lazy_static", - "windows-sys 0.48.0", -] - -[[package]] -name = "console" -version = "0.15.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" -dependencies = [ - "encode_unicode", - "lazy_static", - "libc", - "unicode-width", - "windows-sys 0.52.0", -] - -[[package]] -name = "const-fnv1a-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b13ea120a812beba79e34316b3942a857c86ec1593cb34f27bb28272ce2cca" - -[[package]] -name = "const_format" -version = "0.2.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" -dependencies = [ - "const_format_proc_macros", -] - -[[package]] -name = "const_format_proc_macros" -version = "0.2.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "constant_time_eq" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" - -[[package]] -name = "convert_case" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "cpufeatures" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" -dependencies = [ - "libc", -] - -[[package]] -name = "crc32fast" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "create-output-dir" -version = "1.0.0" -source = "git+https://github.com/software-mansion/scarb?tag=v2.8.2#a37b4cbfc9d7560e4d1375a3b1707c165aedd22a" -dependencies = [ - "anyhow", - "core-foundation 0.10.0", - "tempfile", - "winapi 0.3.9", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "crypto-bigint" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" -dependencies = [ - "generic-array", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "darling" -version = "0.20.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.20.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 2.0.77", -] - -[[package]] -name = "darling_macro" -version = "0.20.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" -dependencies = [ - "darling_core", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "dashmap" -version = "5.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" -dependencies = [ - "cfg-if 1.0.0", - "hashbrown 0.14.5", - "lock_api", - "once_cell", - "parking_lot_core 0.9.10", -] - -[[package]] -name = "dashmap" -version = "6.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" -dependencies = [ - "cfg-if 1.0.0", - "crossbeam-utils", - "hashbrown 0.14.5", - "lock_api", - "once_cell", - "parking_lot_core 0.9.10", -] - -[[package]] -name = "data-encoding" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" - -[[package]] -name = "deno_task_shell" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec1b0c646a53492068b6675af74cecbef486e670be2c0cdd06e7e636d167e50f" -dependencies = [ - "anyhow", - "futures", - "glob", - "monch", - "os_pipe", - "path-dedot", - "thiserror", - "tokio", - "tokio-util", -] - -[[package]] -name = "deranged" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" -dependencies = [ - "powerfmt", -] - -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "derive_builder" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd33f37ee6a119146a1781d3356a7c26028f83d779b2e04ecd45fdc75c76877b" -dependencies = [ - "derive_builder_macro", -] - -[[package]] -name = "derive_builder_core" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7431fa049613920234f22c47fdc33e6cf3ee83067091ea4277a3f8c4587aae38" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "derive_builder_macro" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4abae7035bf79b9877b779505d8cf3749285b80c43941eda66604841889451dc" -dependencies = [ - "derive_builder_core", - "syn 2.0.77", -] - -[[package]] -name = "dialoguer" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658bce805d770f407bc62102fca7c2c64ceef2fbcb2b8bd19d2765ce093980de" -dependencies = [ - "console", - "shell-words", - "tempfile", - "thiserror", - "zeroize", -] - -[[package]] -name = "diff" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" - -[[package]] -name = "difference" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" - -[[package]] -name = "diffy" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e616e59155c92257e84970156f506287853355f58cd4a6eb167385722c32b790" -dependencies = [ - "nu-ansi-term", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "crypto-common", - "subtle", -] - -[[package]] -name = "directories" -version = "5.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-next" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" -dependencies = [ - "cfg-if 1.0.0", - "dirs-sys-next", -] - -[[package]] -name = "dirs-sys" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" -dependencies = [ - "libc", - "option-ext", - "redox_users", - "windows-sys 0.48.0", -] - -[[package]] -name = "dirs-sys-next" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" -dependencies = [ - "libc", - "redox_users", - "winapi 0.3.9", -] - -[[package]] -name = "dunce" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" - -[[package]] -name = "dyn-clone" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" - -[[package]] -name = "either" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" - -[[package]] -name = "ena" -version = "0.14.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5" -dependencies = [ - "log", -] - -[[package]] -name = "encode_unicode" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" - -[[package]] -name = "encoding_rs" -version = "0.8.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "env_filter" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab" -dependencies = [ - "log", - "regex", -] - -[[package]] -name = "env_logger" -version = "0.11.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d" -dependencies = [ - "anstream", - "anstyle", - "env_filter", - "humantime", - "log", -] - -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - -[[package]] -name = "erased-serde" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24e2389d65ab4fab27dc2a5de7b191e1f6617d1f1c8855c0dc569c94a4cbb18d" -dependencies = [ - "serde", - "typeid", -] - -[[package]] -name = "errno" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "escargot" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ceb9adbf9874d5d028b5e4c5739d22b71988252b25c9c98fe7cf9738bee84597" -dependencies = [ - "lazy_static", - "log", - "serde", - "serde_json", -] - -[[package]] -name = "faster-hex" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2a2b11eda1d40935b26cf18f6833c526845ae8c41e58d09af6adeb6f0269183" - -[[package]] -name = "fastrand" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" - -[[package]] -name = "filetime" -version = "0.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "libredox", - "windows-sys 0.59.0", -] - -[[package]] -name = "fixedbitset" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" - -[[package]] -name = "flate2" -version = "1.0.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253" -dependencies = [ - "crc32fast", - "miniz_oxide 0.8.0", -] - -[[package]] -name = "float-cmp" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1267f4ac4f343772758f7b1bdcbe767c218bbab93bb432acbf5162bbf85a6c4" -dependencies = [ - "num-traits 0.2.19", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] -name = "form_urlencoded" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "fs4" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29f9df8a11882c4e3335eb2d18a0137c505d9ca927470b0cac9c6f0ae07d28f7" -dependencies = [ - "async-trait", - "rustix", - "tokio", - "windows-sys 0.48.0", -] - -[[package]] -name = "fs_extra" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" - -[[package]] -name = "fsevent" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6" -dependencies = [ - "bitflags 1.3.2", - "fsevent-sys", -] - -[[package]] -name = "fsevent-sys" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f41b048a94555da0f42f1d632e2e19510084fb8e303b0daa2816e733fb3644a0" -dependencies = [ - "libc", -] - -[[package]] -name = "fuchsia-zircon" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -dependencies = [ - "bitflags 1.3.2", - "fuchsia-zircon-sys", -] - -[[package]] -name = "fuchsia-zircon-sys" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" - -[[package]] -name = "funty" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - -[[package]] -name = "futures" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" - -[[package]] -name = "futures-executor" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" - -[[package]] -name = "futures-macro" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "futures-sink" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" - -[[package]] -name = "futures-task" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" - -[[package]] -name = "futures-util" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "genco" -version = "0.17.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afac3cbb14db69ac9fef9cdb60d8a87e39a7a527f85a81a923436efa40ad42c6" -dependencies = [ - "genco-macros", - "relative-path", - "smallvec", -] - -[[package]] -name = "genco-macros" -version = "0.17.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "553630feadf7b76442b0849fd25fdf89b860d933623aec9693fed19af0400c78" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" -dependencies = [ - "cfg-if 1.0.0", - "js-sys", - "libc", - "wasi", - "wasm-bindgen", -] - -[[package]] -name = "gimli" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" - -[[package]] -name = "gix" -version = "0.66.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9048b8d1ae2104f045cb37e5c450fc49d5d8af22609386bfc739c11ba88995eb" -dependencies = [ - "gix-actor", - "gix-archive", - "gix-attributes", - "gix-command", - "gix-commitgraph", - "gix-config", - "gix-credentials", - "gix-date", - "gix-diff", - "gix-dir", - "gix-discover", - "gix-features", - "gix-filter", - "gix-fs", - "gix-glob", - "gix-hash", - "gix-hashtable", - "gix-ignore", - "gix-index", - "gix-lock", - "gix-mailmap", - "gix-negotiate", - "gix-object", - "gix-odb", - "gix-pack", - "gix-path", - "gix-pathspec", - "gix-prompt", - "gix-ref", - "gix-refspec", - "gix-revision", - "gix-revwalk", - "gix-sec", - "gix-status", - "gix-submodule", - "gix-tempfile", - "gix-trace", - "gix-traverse", - "gix-url", - "gix-utils", - "gix-validate", - "gix-worktree", - "gix-worktree-state", - "gix-worktree-stream", - "once_cell", - "parking_lot 0.12.3", - "regex", - "signal-hook", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-actor" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc19e312cd45c4a66cd003f909163dc2f8e1623e30a0c0c6df3776e89b308665" -dependencies = [ - "bstr", - "gix-date", - "gix-utils", - "itoa", - "thiserror", - "winnow", -] - -[[package]] -name = "gix-archive" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9147c08a55c1398b755539e2cdd63ff690ffe4a2e5e5e0780ee6ef2b49b0a60a" -dependencies = [ - "bstr", - "gix-date", - "gix-object", - "gix-worktree-stream", - "jiff", - "thiserror", -] - -[[package]] -name = "gix-attributes" -version = "0.22.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebccbf25aa4a973dd352564a9000af69edca90623e8a16dad9cbc03713131311" -dependencies = [ - "bstr", - "gix-glob", - "gix-path", - "gix-quote", - "gix-trace", - "kstring", - "smallvec", - "thiserror", - "unicode-bom", -] - -[[package]] -name = "gix-bitmap" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a371db66cbd4e13f0ed9dc4c0fea712d7276805fccc877f77e96374d317e87ae" -dependencies = [ - "thiserror", -] - -[[package]] -name = "gix-chunk" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45c8751169961ba7640b513c3b24af61aa962c967aaf04116734975cd5af0c52" -dependencies = [ - "thiserror", -] - -[[package]] -name = "gix-command" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff2e692b36bbcf09286c70803006ca3fd56551a311de450be317a0ab8ea92e7" -dependencies = [ - "bstr", - "gix-path", - "gix-trace", - "shell-words", -] - -[[package]] -name = "gix-commitgraph" -version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "133b06f67f565836ec0c473e2116a60fb74f80b6435e21d88013ac0e3c60fc78" -dependencies = [ - "bstr", - "gix-chunk", - "gix-features", - "gix-hash", - "memmap2", - "thiserror", -] - -[[package]] -name = "gix-config" -version = "0.40.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78e797487e6ca3552491de1131b4f72202f282fb33f198b1c34406d765b42bb0" -dependencies = [ - "bstr", - "gix-config-value", - "gix-features", - "gix-glob", - "gix-path", - "gix-ref", - "gix-sec", - "memchr", - "once_cell", - "smallvec", - "thiserror", - "unicode-bom", - "winnow", -] - -[[package]] -name = "gix-config-value" -version = "0.14.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03f76169faa0dec598eac60f83d7fcdd739ec16596eca8fb144c88973dbe6f8c" -dependencies = [ - "bitflags 2.6.0", - "bstr", - "gix-path", - "libc", - "thiserror", -] - -[[package]] -name = "gix-credentials" -version = "0.24.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce391d305968782f1ae301c4a3d42c5701df7ff1d8bc03740300f6fd12bce78" -dependencies = [ - "bstr", - "gix-command", - "gix-config-value", - "gix-path", - "gix-prompt", - "gix-sec", - "gix-trace", - "gix-url", - "thiserror", -] - -[[package]] -name = "gix-date" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35c84b7af01e68daf7a6bb8bb909c1ff5edb3ce4326f1f43063a5a96d3c3c8a5" -dependencies = [ - "bstr", - "itoa", - "jiff", - "thiserror", -] - -[[package]] -name = "gix-diff" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92c9afd80fff00f8b38b1c1928442feb4cd6d2232a6ed806b6b193151a3d336c" -dependencies = [ - "bstr", - "gix-command", - "gix-filter", - "gix-fs", - "gix-hash", - "gix-object", - "gix-path", - "gix-tempfile", - "gix-trace", - "gix-worktree", - "imara-diff", - "thiserror", -] - -[[package]] -name = "gix-dir" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ed3a9076661359a1c5a27c12ad6c3ebe2dd96b8b3c0af6488ab7c128b7bdd98" -dependencies = [ - "bstr", - "gix-discover", - "gix-fs", - "gix-ignore", - "gix-index", - "gix-object", - "gix-path", - "gix-pathspec", - "gix-trace", - "gix-utils", - "gix-worktree", - "thiserror", -] - -[[package]] -name = "gix-discover" -version = "0.35.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0577366b9567376bc26e815fd74451ebd0e6218814e242f8e5b7072c58d956d2" -dependencies = [ - "bstr", - "dunce", - "gix-fs", - "gix-hash", - "gix-path", - "gix-ref", - "gix-sec", - "thiserror", -] - -[[package]] -name = "gix-features" -version = "0.38.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac7045ac9fe5f9c727f38799d002a7ed3583cd777e3322a7c4b43e3cf437dc69" -dependencies = [ - "bytes", - "bytesize", - "crc32fast", - "crossbeam-channel", - "flate2", - "gix-hash", - "gix-trace", - "gix-utils", - "libc", - "once_cell", - "parking_lot 0.12.3", - "prodash", - "sha1_smol", - "thiserror", - "walkdir", -] - -[[package]] -name = "gix-filter" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4121790ae140066e5b953becc72e7496278138d19239be2e63b5067b0843119e" -dependencies = [ - "bstr", - "encoding_rs", - "gix-attributes", - "gix-command", - "gix-hash", - "gix-object", - "gix-packetline-blocking", - "gix-path", - "gix-quote", - "gix-trace", - "gix-utils", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-fs" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2bfe6249cfea6d0c0e0990d5226a4cb36f030444ba9e35e0639275db8f98575" -dependencies = [ - "fastrand", - "gix-features", - "gix-utils", -] - -[[package]] -name = "gix-glob" -version = "0.16.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74908b4bbc0a0a40852737e5d7889f676f081e340d5451a16e5b4c50d592f111" -dependencies = [ - "bitflags 2.6.0", - "bstr", - "gix-features", - "gix-path", -] - -[[package]] -name = "gix-hash" -version = "0.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93d7df7366121b5018f947a04d37f034717e113dcf9ccd85c34b58e57a74d5e" -dependencies = [ - "faster-hex", - "thiserror", -] - -[[package]] -name = "gix-hashtable" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ddf80e16f3c19ac06ce415a38b8591993d3f73aede049cb561becb5b3a8e242" -dependencies = [ - "gix-hash", - "hashbrown 0.14.5", - "parking_lot 0.12.3", -] - -[[package]] -name = "gix-ignore" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e447cd96598460f5906a0f6c75e950a39f98c2705fc755ad2f2020c9e937fab7" -dependencies = [ - "bstr", - "gix-glob", - "gix-path", - "gix-trace", - "unicode-bom", -] - -[[package]] -name = "gix-index" -version = "0.35.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cd4203244444017682176e65fd0180be9298e58ed90bd4a8489a357795ed22d" -dependencies = [ - "bitflags 2.6.0", - "bstr", - "filetime", - "fnv", - "gix-bitmap", - "gix-features", - "gix-fs", - "gix-hash", - "gix-lock", - "gix-object", - "gix-traverse", - "gix-utils", - "gix-validate", - "hashbrown 0.14.5", - "itoa", - "libc", - "memmap2", - "rustix", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-lock" -version = "14.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bc7fe297f1f4614774989c00ec8b1add59571dc9b024b4c00acb7dedd4e19d" -dependencies = [ - "gix-tempfile", - "gix-utils", - "thiserror", -] - -[[package]] -name = "gix-mailmap" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7d522c8ec2501e1a5b2b4cb54e83cb5d9a52471c9d23b3a1e8dadaf063752f7" -dependencies = [ - "bstr", - "gix-actor", - "gix-date", - "thiserror", -] - -[[package]] -name = "gix-negotiate" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4063bf329a191a9e24b6f948a17ccf6698c0380297f5e169cee4f1d2ab9475b" -dependencies = [ - "bitflags 2.6.0", - "gix-commitgraph", - "gix-date", - "gix-hash", - "gix-object", - "gix-revwalk", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-object" -version = "0.44.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f5b801834f1de7640731820c2df6ba88d95480dc4ab166a5882f8ff12b88efa" -dependencies = [ - "bstr", - "gix-actor", - "gix-date", - "gix-features", - "gix-hash", - "gix-utils", - "gix-validate", - "itoa", - "smallvec", - "thiserror", - "winnow", -] - -[[package]] -name = "gix-odb" -version = "0.63.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3158068701c17df54f0ab2adda527f5a6aca38fd5fd80ceb7e3c0a2717ec747" -dependencies = [ - "arc-swap", - "gix-date", - "gix-features", - "gix-fs", - "gix-hash", - "gix-object", - "gix-pack", - "gix-path", - "gix-quote", - "parking_lot 0.12.3", - "tempfile", - "thiserror", -] - -[[package]] -name = "gix-pack" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3223aa342eee21e1e0e403cad8ae9caf9edca55ef84c347738d10681676fd954" -dependencies = [ - "clru", - "gix-chunk", - "gix-features", - "gix-hash", - "gix-hashtable", - "gix-object", - "gix-path", - "memmap2", - "smallvec", - "thiserror", - "uluru", -] - -[[package]] -name = "gix-packetline-blocking" -version = "0.17.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9802304baa798dd6f5ff8008a2b6516d54b74a69ca2d3a2b9e2d6c3b5556b40" -dependencies = [ - "bstr", - "faster-hex", - "gix-trace", - "thiserror", -] - -[[package]] -name = "gix-path" -version = "0.10.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d5b8722112fa2fa87135298780bc833b0e9f6c56cc82795d209804b3a03484" -dependencies = [ - "bstr", - "gix-trace", - "home", - "once_cell", - "thiserror", -] - -[[package]] -name = "gix-pathspec" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d23bf239532b4414d0e63b8ab3a65481881f7237ed9647bb10c1e3cc54c5ceb" -dependencies = [ - "bitflags 2.6.0", - "bstr", - "gix-attributes", - "gix-config-value", - "gix-glob", - "gix-path", - "thiserror", -] - -[[package]] -name = "gix-prompt" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74fde865cdb46b30d8dad1293385d9bcf998d3a39cbf41bee67d0dab026fe6b1" -dependencies = [ - "gix-command", - "gix-config-value", - "parking_lot 0.12.3", - "rustix", - "thiserror", -] - -[[package]] -name = "gix-quote" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbff4f9b9ea3fa7a25a70ee62f545143abef624ac6aa5884344e70c8b0a1d9ff" -dependencies = [ - "bstr", - "gix-utils", - "thiserror", -] - -[[package]] -name = "gix-ref" -version = "0.47.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae0d8406ebf9aaa91f55a57f053c5a1ad1a39f60fdf0303142b7be7ea44311e5" -dependencies = [ - "gix-actor", - "gix-features", - "gix-fs", - "gix-hash", - "gix-lock", - "gix-object", - "gix-path", - "gix-tempfile", - "gix-utils", - "gix-validate", - "memmap2", - "thiserror", - "winnow", -] - -[[package]] -name = "gix-refspec" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebb005f82341ba67615ffdd9f7742c87787544441c88090878393d0682869ca6" -dependencies = [ - "bstr", - "gix-hash", - "gix-revision", - "gix-validate", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-revision" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4621b219ac0cdb9256883030c3d56a6c64a6deaa829a92da73b9a576825e1e" -dependencies = [ - "bstr", - "gix-date", - "gix-hash", - "gix-hashtable", - "gix-object", - "gix-revwalk", - "gix-trace", - "thiserror", -] - -[[package]] -name = "gix-revwalk" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b41e72544b93084ee682ef3d5b31b1ba4d8fa27a017482900e5e044d5b1b3984" -dependencies = [ - "gix-commitgraph", - "gix-date", - "gix-hash", - "gix-hashtable", - "gix-object", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-sec" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fe4d52f30a737bbece5276fab5d3a8b276dc2650df963e293d0673be34e7a5f" -dependencies = [ - "bitflags 2.6.0", - "gix-path", - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "gix-status" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f70d35ba639f0c16a6e4cca81aa374a05f07b23fa36ee8beb72c100d98b4ffea" -dependencies = [ - "bstr", - "filetime", - "gix-diff", - "gix-dir", - "gix-features", - "gix-filter", - "gix-fs", - "gix-hash", - "gix-index", - "gix-object", - "gix-path", - "gix-pathspec", - "gix-worktree", - "portable-atomic", - "thiserror", -] - -[[package]] -name = "gix-submodule" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "529d0af78cc2f372b3218f15eb1e3d1635a21c8937c12e2dd0b6fc80c2ca874b" -dependencies = [ - "bstr", - "gix-config", - "gix-path", - "gix-pathspec", - "gix-refspec", - "gix-url", - "thiserror", -] - -[[package]] -name = "gix-tempfile" -version = "14.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046b4927969fa816a150a0cda2e62c80016fe11fb3c3184e4dddf4e542f108aa" -dependencies = [ - "dashmap 6.1.0", - "gix-fs", - "libc", - "once_cell", - "parking_lot 0.12.3", - "signal-hook", - "signal-hook-registry", - "tempfile", -] - -[[package]] -name = "gix-trace" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f924267408915fddcd558e3f37295cc7d6a3e50f8bd8b606cee0808c3915157e" - -[[package]] -name = "gix-traverse" -version = "0.41.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "030da39af94e4df35472e9318228f36530989327906f38e27807df305fccb780" -dependencies = [ - "bitflags 2.6.0", - "gix-commitgraph", - "gix-date", - "gix-hash", - "gix-hashtable", - "gix-object", - "gix-revwalk", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-url" -version = "0.27.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd280c5e84fb22e128ed2a053a0daeacb6379469be6a85e3d518a0636e160c89" -dependencies = [ - "bstr", - "gix-features", - "gix-path", - "home", - "thiserror", - "url", -] - -[[package]] -name = "gix-utils" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35192df7fd0fa112263bad8021e2df7167df4cc2a6e6d15892e1e55621d3d4dc" -dependencies = [ - "bstr", - "fastrand", - "unicode-normalization", -] - -[[package]] -name = "gix-validate" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81f2badbb64e57b404593ee26b752c26991910fd0d81fe6f9a71c1a8309b6c86" -dependencies = [ - "bstr", - "thiserror", -] - -[[package]] -name = "gix-worktree" -version = "0.36.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c312ad76a3f2ba8e865b360d5cb3aa04660971d16dec6dd0ce717938d903149a" -dependencies = [ - "bstr", - "gix-attributes", - "gix-features", - "gix-fs", - "gix-glob", - "gix-hash", - "gix-ignore", - "gix-index", - "gix-object", - "gix-path", - "gix-validate", -] - -[[package]] -name = "gix-worktree-state" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b05c4b313fa702c0bacd5068dd3e01671da73b938fade97676859fee286de43" -dependencies = [ - "bstr", - "gix-features", - "gix-filter", - "gix-fs", - "gix-glob", - "gix-hash", - "gix-index", - "gix-object", - "gix-path", - "gix-worktree", - "io-close", - "thiserror", -] - -[[package]] -name = "gix-worktree-stream" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68e81b87c1a3ece22a54b682d6fdc37fbb3977132da972cafe5ec07175fddbca" -dependencies = [ - "gix-attributes", - "gix-features", - "gix-filter", - "gix-fs", - "gix-hash", - "gix-object", - "gix-path", - "gix-traverse", - "parking_lot 0.12.3", - "thiserror", -] - -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - -[[package]] -name = "globset" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" -dependencies = [ - "aho-corasick", - "bstr", - "log", - "regex-automata 0.4.7", - "regex-syntax 0.8.4", -] - -[[package]] -name = "good_lp" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3198bd13dea84c76a64621d6ee8ee26a4960a9a0d538eca95ca8f1320a469ac9" -dependencies = [ - "fnv", - "minilp", -] - -[[package]] -name = "h2" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap 2.5.0", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - -[[package]] -name = "hashbrown" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" -dependencies = [ - "ahash", - "allocator-api2", - "serde", -] - -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest", -] - -[[package]] -name = "home" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "http" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes", - "http", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" - -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - -[[package]] -name = "human_format" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c3b1f728c459d27b12448862017b96ad4767b1ec2ec5e6434e99f1577f085b8" - -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - -[[package]] -name = "hyper" -version = "0.14.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" -dependencies = [ - "futures-util", - "http", - "hyper", - "rustls", - "tokio", - "tokio-rustls", -] - -[[package]] -name = "hyper-tls" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" -dependencies = [ - "bytes", - "hyper", - "native-tls", - "tokio", - "tokio-native-tls", -] - -[[package]] -name = "id-arena" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" - -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - -[[package]] -name = "idna" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "ignore" -version = "0.4.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1" -dependencies = [ - "crossbeam-deque", - "globset", - "log", - "memchr", - "regex-automata 0.4.7", - "same-file", - "walkdir", - "winapi-util", -] - -[[package]] -name = "imara-diff" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc9da1a252bd44cd341657203722352efc9bc0c847d06ea6d2dc1cd1135e0a01" -dependencies = [ - "ahash", - "hashbrown 0.14.5", -] - -[[package]] -name = "impl-trait-for-tuples" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "include_dir" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "923d117408f1e49d914f1a379a309cffe4f18c05cf4e3d12e613a15fc81bd0dd" -dependencies = [ - "include_dir_macros", -] - -[[package]] -name = "include_dir_macros" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cab85a7ed0bd5f0e76d93846e0147172bed2e2d3f859bcc33a8d9699cad1a75" -dependencies = [ - "proc-macro2", - "quote", -] - -[[package]] -name = "indent" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9f1a0777d972970f204fdf8ef319f1f4f8459131636d7e3c96c5d59570d0fa6" - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", -] - -[[package]] -name = "indexmap" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" -dependencies = [ - "equivalent", - "hashbrown 0.14.5", - "serde", -] - -[[package]] -name = "indicatif" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d207dc617c7a380ab07ff572a6e52fa202a2a8f355860ac9c38e23f8196be1b" -dependencies = [ - "console", - "lazy_static", - "number_prefix", - "regex", -] - -[[package]] -name = "indicatif" -version = "0.17.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" -dependencies = [ - "console", - "instant", - "number_prefix", - "portable-atomic", - "unicode-width", -] - -[[package]] -name = "indoc" -version = "2.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" - -[[package]] -name = "inotify" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4816c66d2c8ae673df83366c18341538f234a26d65a9ecea5c348b453ac1d02f" -dependencies = [ - "bitflags 1.3.2", - "inotify-sys", - "libc", -] - -[[package]] -name = "inotify-sys" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" -dependencies = [ - "libc", -] - -[[package]] -name = "inout" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" -dependencies = [ - "generic-array", -] - -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "io-close" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cadcf447f06744f8ce713d2d6239bb5bde2c357a452397a9ed90c625da390bc" -dependencies = [ - "libc", - "winapi 0.3.9", -] - -[[package]] -name = "iovec" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" -dependencies = [ - "libc", -] - -[[package]] -name = "ipnet" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" - -[[package]] -name = "is_terminal_polyfill" -version = "1.70.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" - -[[package]] -name = "jiff" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "437651126da47900d4d70255ab15f5c69510ca4e0d88c9f01b5b8d41a45c3a9b" -dependencies = [ - "jiff-tzdb-platform", - "windows-sys 0.59.0", -] - -[[package]] -name = "jiff-tzdb" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05fac328b3df1c0f18a3c2ab6cb7e06e4e549f366017d796e3e66b6d6889abe6" - -[[package]] -name = "jiff-tzdb-platform" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8da387d5feaf355954c2c122c194d6df9c57d865125a67984bb453db5336940" -dependencies = [ - "jiff-tzdb", -] - -[[package]] -name = "jobserver" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" -dependencies = [ - "libc", -] - -[[package]] -name = "js-sys" -version = "0.3.70" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "keccak" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" -dependencies = [ - "cpufeatures", -] - -[[package]] -name = "kernel32-sys" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -dependencies = [ - "winapi 0.2.8", - "winapi-build", -] - -[[package]] -name = "kstring" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "558bf9508a558512042d3095138b1f7b8fe90c5467d94f9f1da28b3731c5dbd1" -dependencies = [ - "static_assertions", -] - -[[package]] -name = "lalrpop" -version = "0.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cb077ad656299f160924eb2912aa147d7339ea7d69e1b5517326fdcec3c1ca" -dependencies = [ - "ascii-canvas", - "bit-set", - "ena", - "itertools 0.11.0", - "lalrpop-util", - "petgraph", - "pico-args", - "regex", - "regex-syntax 0.8.4", - "string_cache", - "term", - "tiny-keccak", - "unicode-xid", - "walkdir", -] - -[[package]] -name = "lalrpop-util" -version = "0.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "507460a910eb7b32ee961886ff48539633b788a36b65692b95f225b844c82553" -dependencies = [ - "regex-automata 0.4.7", -] - -[[package]] -name = "lambdaworks-crypto" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fb5d4f22241504f7c7b8d2c3a7d7835d7c07117f10bff2a7d96a9ef6ef217c3" -dependencies = [ - "lambdaworks-math", - "serde", - "sha2", - "sha3", -] - -[[package]] -name = "lambdaworks-math" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "358e172628e713b80a530a59654154bfc45783a6ed70ea284839800cebdf8f97" -dependencies = [ - "serde", - "serde_json", -] - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" -dependencies = [ - "spin", -] - -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - -[[package]] -name = "libc" -version = "0.2.158" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" - -[[package]] -name = "libloading" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" -dependencies = [ - "cfg-if 1.0.0", - "windows-targets 0.52.6", -] - -[[package]] -name = "libredox" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" -dependencies = [ - "bitflags 2.6.0", - "libc", - "redox_syscall 0.5.3", -] - -[[package]] -name = "linkme" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c943daedff228392b791b33bba32e75737756e80a613e32e246c6ce9cbab20a" -dependencies = [ - "linkme-impl", -] - -[[package]] -name = "linkme-impl" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb26336e6dc7cc76e7927d2c9e7e3bb376d7af65a6f56a0b16c47d18a9b1abc5" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "linux-raw-sys" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" - -[[package]] -name = "lock_api" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" - -[[package]] -name = "lru" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37ee39891760e7d94734f6f63fedc29a2e4a152f836120753a72503f09fcf904" -dependencies = [ - "hashbrown 0.14.5", -] - -[[package]] -name = "matchers" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" -dependencies = [ - "regex-automata 0.1.10", -] - -[[package]] -name = "matrixmultiply" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "916806ba0031cd542105d916a97c8572e1fa6dd79c9c51e7eb43a09ec2dd84c1" -dependencies = [ - "rawpointer", -] - -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "memmap2" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322" -dependencies = [ - "libc", -] - -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - -[[package]] -name = "mime_guess" -version = "2.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" -dependencies = [ - "mime", - "unicase", -] - -[[package]] -name = "minilp" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82a7750a9e5076c660b7bec5e6457b4dbff402b9863c8d112891434e18fd5385" -dependencies = [ - "log", - "sprs", -] - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "miniz_oxide" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" -dependencies = [ - "adler", -] - -[[package]] -name = "miniz_oxide" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" -dependencies = [ - "adler2", -] - -[[package]] -name = "mio" -version = "0.6.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" -dependencies = [ - "cfg-if 0.1.10", - "fuchsia-zircon", - "fuchsia-zircon-sys", - "iovec", - "kernel32-sys", - "libc", - "log", - "miow", - "net2", - "slab", - "winapi 0.2.8", -] - -[[package]] -name = "mio" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" -dependencies = [ - "hermit-abi", - "libc", - "wasi", - "windows-sys 0.52.0", -] - -[[package]] -name = "mio-extras" -version = "2.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" -dependencies = [ - "lazycell", - "log", - "mio 0.6.23", - "slab", -] - -[[package]] -name = "miow" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" -dependencies = [ - "kernel32-sys", - "net2", - "winapi 0.2.8", - "ws2_32-sys", -] - -[[package]] -name = "monch" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b52c1b33ff98142aecea13138bd399b68aa7ab5d9546c300988c345004001eea" - -[[package]] -name = "native-tls" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" -dependencies = [ - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - -[[package]] -name = "ndarray" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac06db03ec2f46ee0ecdca1a1c34a99c0d188a0d83439b84bf0cb4b386e4ab09" -dependencies = [ - "matrixmultiply", - "num-complex", - "num-integer", - "num-traits 0.2.19", - "rawpointer", -] - -[[package]] -name = "net2" -version = "0.2.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b13b648036a2339d06de780866fbdfda0dde886de7b3af2ddeba8b14f4ee34ac" -dependencies = [ - "cfg-if 0.1.10", - "libc", - "winapi 0.3.9", -] - -[[package]] -name = "new_debug_unreachable" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "normalize-line-endings" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" - -[[package]] -name = "notify" -version = "4.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b72dd35279a5dc895a30965e247b0961ba36c233dc48454a2de8ccd459f1afd3" -dependencies = [ - "bitflags 1.3.2", - "filetime", - "fsevent", - "fsevent-sys", - "inotify", - "libc", - "mio 0.6.23", - "mio-extras", - "walkdir", - "winapi 0.3.9", -] - -[[package]] -name = "nu-ansi-term" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" -dependencies = [ - "overload", - "winapi 0.3.9", -] - -[[package]] -name = "num-bigint" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" -dependencies = [ - "num-integer", - "num-traits 0.2.19", - "rand", - "serde", -] - -[[package]] -name = "num-complex" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95" -dependencies = [ - "autocfg", - "num-traits 0.2.19", -] - -[[package]] -name = "num-conv" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits 0.2.19", -] - -[[package]] -name = "num-modular" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a5fe11d4135c3bcdf3a95b18b194afa9608a5f6ff034f5d857bc9a27fb0119" -dependencies = [ - "num-bigint", - "num-integer", - "num-traits 0.2.19", -] - -[[package]] -name = "num-prime" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e238432a7881ec7164503ccc516c014bf009be7984cde1ba56837862543bdec3" -dependencies = [ - "bitvec", - "either", - "lru", - "num-bigint", - "num-integer", - "num-modular", - "num-traits 0.2.19", - "rand", -] - -[[package]] -name = "num-traits" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" -dependencies = [ - "num-traits 0.2.19", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_threads" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" -dependencies = [ - "libc", -] - -[[package]] -name = "number_prefix" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" - -[[package]] -name = "object" -version = "0.36.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" - -[[package]] -name = "oorandom" -version = "11.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" - -[[package]] -name = "openssl" -version = "0.10.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" -dependencies = [ - "bitflags 2.6.0", - "cfg-if 1.0.0", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - -[[package]] -name = "openssl-sys" -version = "0.9.103" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "option-ext" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" - -[[package]] -name = "ordered-float" -version = "2.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c" -dependencies = [ - "num-traits 0.2.19", -] - -[[package]] -name = "os_pipe" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ffd2b0a5634335b135d5728d84c5e0fd726954b87111f7506a61c502280d982" -dependencies = [ - "libc", - "windows-sys 0.59.0", -] - -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - -[[package]] -name = "parity-scale-codec" -version = "3.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" -dependencies = [ - "arrayvec", - "bitvec", - "byte-slice-cast", - "impl-trait-for-tuples", - "parity-scale-codec-derive", - "serde", -] - -[[package]] -name = "parity-scale-codec-derive" -version = "3.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.6", -] - -[[package]] -name = "parking_lot" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" -dependencies = [ - "lock_api", - "parking_lot_core 0.9.10", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" -dependencies = [ - "cfg-if 1.0.0", - "instant", - "libc", - "redox_syscall 0.2.16", - "smallvec", - "winapi 0.3.9", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "redox_syscall 0.5.3", - "smallvec", - "windows-targets 0.52.6", -] - -[[package]] -name = "password-hash" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" -dependencies = [ - "base64ct", - "rand_core", - "subtle", -] - -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "path-clean" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17359afc20d7ab31fdb42bb844c8b3bb1dabd7dcf7e68428492da7f16966fcef" - -[[package]] -name = "path-dedot" -version = "3.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07ba0ad7e047712414213ff67533e6dd477af0a4e1d14fb52343e53d30ea9397" -dependencies = [ - "once_cell", -] - -[[package]] -name = "pathdiff" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" -dependencies = [ - "camino", -] - -[[package]] -name = "pbkdf2" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" -dependencies = [ - "digest", - "hmac", - "password-hash", - "sha2", -] - -[[package]] -name = "percent-encoding" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" - -[[package]] -name = "petgraph" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" -dependencies = [ - "fixedbitset", - "indexmap 2.5.0", -] - -[[package]] -name = "phf_shared" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" -dependencies = [ - "siphasher", -] - -[[package]] -name = "pico-args" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" - -[[package]] -name = "pin-project-lite" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkg-config" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" - -[[package]] -name = "portable-atomic" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265" - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - -[[package]] -name = "ppv-lite86" -version = "0.2.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "precomputed-hash" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" - -[[package]] -name = "predicates" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f49cfaf7fdaa3bfacc6fa3e7054e65148878354a5cfddcf661df4c851f8021df" -dependencies = [ - "difference", - "float-cmp", - "normalize-line-endings", - "predicates-core", - "regex", -] - -[[package]] -name = "predicates-core" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae8177bee8e75d6846599c6b9ff679ed51e882816914eec639944d7c9aa11931" - -[[package]] -name = "predicates-tree" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41b740d195ed3166cd147c8047ec98db0e22ec019eb8eeb76d343b795304fb13" -dependencies = [ - "predicates-core", - "termtree", -] - -[[package]] -name = "pretty_assertions" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" -dependencies = [ - "diff", - "yansi", -] - -[[package]] -name = "proc-macro-crate" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" -dependencies = [ - "toml_edit", -] - -[[package]] -name = "proc-macro2" -version = "1.0.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "prodash" -version = "28.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744a264d26b88a6a7e37cbad97953fa233b94d585236310bcbc88474b4092d79" -dependencies = [ - "bytesize", - "human_format", -] - -[[package]] -name = "quote" -version = "1.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "ra_ap_toolchain" -version = "0.0.218" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53393fc4d85057bcca4dd2d7fa24929a094bb94712980814695f56cb9aa0b1e2" -dependencies = [ - "camino", - "home", -] - -[[package]] -name = "radium" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rawpointer" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" - -[[package]] -name = "rayon" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed02d09394c94ffbdfdc755ad62a132e94c3224a8354e78a1200ced34df12edf" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - -[[package]] -name = "redb" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58323dc32ea52a8ae105ff94bc0460c5d906307533ba3401aa63db3cbe491fe5" -dependencies = [ - "libc", -] - -[[package]] -name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_syscall" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" -dependencies = [ - "bitflags 2.6.0", -] - -[[package]] -name = "redox_users" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" -dependencies = [ - "getrandom", - "libredox", - "thiserror", -] - -[[package]] -name = "regex" -version = "1.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata 0.4.7", - "regex-syntax 0.8.4", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", -] - -[[package]] -name = "regex-automata" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax 0.8.4", -] - -[[package]] -name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - -[[package]] -name = "regex-syntax" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" - -[[package]] -name = "relative-path" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" - -[[package]] -name = "reqwest" -version = "0.11.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" -dependencies = [ - "async-compression", - "base64", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-rustls", - "hyper-tls", - "ipnet", - "js-sys", - "log", - "mime", - "mime_guess", - "native-tls", - "once_cell", - "percent-encoding", - "pin-project-lite", - "rustls", - "rustls-native-certs", - "rustls-pemfile", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "system-configuration", - "tokio", - "tokio-native-tls", - "tokio-rustls", - "tokio-util", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-streams", - "web-sys", - "winreg", -] - -[[package]] -name = "rfc6979" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" -dependencies = [ - "hmac", - "subtle", -] - -[[package]] -name = "ring" -version = "0.17.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" -dependencies = [ - "cc", - "cfg-if 1.0.0", - "getrandom", - "libc", - "spin", - "untrusted", - "windows-sys 0.52.0", -] - -[[package]] -name = "rust-analyzer-salsa" -version = "0.17.0-pre.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719825638c59fd26a55412a24561c7c5bcf54364c88b9a7a04ba08a6eafaba8d" -dependencies = [ - "indexmap 2.5.0", - "lock_api", - "oorandom", - "parking_lot 0.12.3", - "rust-analyzer-salsa-macros", - "rustc-hash", - "smallvec", - "tracing", - "triomphe", -] - -[[package]] -name = "rust-analyzer-salsa-macros" -version = "0.17.0-pre.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d96498e9684848c6676c399032ebc37c52da95ecbefa83d71ccc53b9f8a4a8e" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "rust_decimal" -version = "1.36.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b082d80e3e3cc52b2ed634388d436fe1f4de6af5786cc2de9ba9737527bdf555" -dependencies = [ - "arrayvec", - "num-traits 0.2.19", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustc_version" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" -dependencies = [ - "semver", -] - -[[package]] -name = "rustix" -version = "0.38.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f55e80d50763938498dd5ebb18647174e0c76dc38c5505294bb224624f30f36" -dependencies = [ - "bitflags 2.6.0", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.52.0", -] - -[[package]] -name = "rustls" -version = "0.21.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" -dependencies = [ - "log", - "ring", - "rustls-webpki", - "sct", -] - -[[package]] -name = "rustls-native-certs" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" -dependencies = [ - "openssl-probe", - "rustls-pemfile", - "schannel", - "security-framework", -] - -[[package]] -name = "rustls-pemfile" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" -dependencies = [ - "base64", -] - -[[package]] -name = "rustls-webpki" -version = "0.101.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "rustversion" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" - -[[package]] -name = "ryu" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" - -[[package]] -name = "salsa" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b84d9f96071f3f3be0dc818eae3327625d8ebc95b58da37d6850724f31d3403" -dependencies = [ - "crossbeam-utils", - "indexmap 1.9.3", - "lock_api", - "log", - "oorandom", - "parking_lot 0.11.2", - "rustc-hash", - "salsa-macros", - "smallvec", -] - -[[package]] -name = "salsa-macros" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd3904a4ba0a9d0211816177fd34b04c7095443f8cdacd11175064fe541c8fe2" -dependencies = [ - "heck 0.3.3", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "scarb" -version = "2.8.2" -source = "git+https://github.com/software-mansion/scarb?tag=v2.8.2#a37b4cbfc9d7560e4d1375a3b1707c165aedd22a" -dependencies = [ - "anyhow", - "async-trait", - "cairo-lang-compiler", - "cairo-lang-defs", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-formatter", - "cairo-lang-lowering", - "cairo-lang-macro", - "cairo-lang-macro-stable", - "cairo-lang-parser", - "cairo-lang-semantic", - "cairo-lang-sierra", - "cairo-lang-sierra-to-casm", - "cairo-lang-starknet", - "cairo-lang-starknet-classes", - "cairo-lang-syntax", - "cairo-lang-test-plugin", - "cairo-lang-utils", - "camino", - "clap", - "convert_case", - "create-output-dir", - "data-encoding", - "deno_task_shell", - "derive_builder", - "dialoguer", - "directories", - "dunce", - "fs4", - "fs_extra", - "futures", - "gix", - "gix-path", - "glob", - "ignore", - "include_dir", - "indoc", - "itertools 0.12.1", - "libloading", - "once_cell", - "pathdiff", - "petgraph", - "ra_ap_toolchain", - "redb", - "reqwest", - "scarb-build-metadata", - "scarb-metadata", - "scarb-stable-hash 1.0.0 (git+https://github.com/software-mansion/scarb?tag=v2.8.2)", - "scarb-ui", - "semver", - "serde", - "serde-untagged", - "serde-value", - "serde_json", - "serde_repr", - "sha2", - "smallvec", - "smol_str", - "tar", - "thiserror", - "tokio", - "toml 0.8.19", - "toml_edit", - "tracing", - "tracing-subscriber", - "typed-builder", - "url", - "walkdir", - "which", - "windows-sys 0.59.0", - "zip", - "zstd 0.13.2", -] - -[[package]] -name = "scarb-build-metadata" -version = "2.8.2" -source = "git+https://github.com/software-mansion/scarb?tag=v2.8.2#a37b4cbfc9d7560e4d1375a3b1707c165aedd22a" -dependencies = [ - "cargo_metadata", -] - -[[package]] -name = "scarb-metadata" -version = "1.12.0" -source = "git+https://github.com/software-mansion/scarb?tag=v2.8.2#a37b4cbfc9d7560e4d1375a3b1707c165aedd22a" -dependencies = [ - "camino", - "derive_builder", - "semver", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "scarb-stable-hash" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1902536b23a05dd165d3992865870aaf1b0650317767cbf171ed2ca5903732a9" -dependencies = [ - "data-encoding", - "xxhash-rust", -] - -[[package]] -name = "scarb-stable-hash" -version = "1.0.0" -source = "git+https://github.com/software-mansion/scarb?tag=v2.8.2#a37b4cbfc9d7560e4d1375a3b1707c165aedd22a" -dependencies = [ - "data-encoding", - "xxhash-rust", -] - -[[package]] -name = "scarb-ui" -version = "0.1.5" -source = "git+https://github.com/software-mansion/scarb?tag=v2.8.2#a37b4cbfc9d7560e4d1375a3b1707c165aedd22a" -dependencies = [ - "anyhow", - "camino", - "clap", - "console", - "indicatif 0.17.8", - "scarb-metadata", - "serde", - "serde_json", - "tracing-core", -] - -[[package]] -name = "schannel" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "schemars" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92" -dependencies = [ - "dyn-clone", - "indexmap 1.9.3", - "schemars_derive", - "serde", - "serde_json", -] - -[[package]] -name = "schemars_derive" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1eee588578aff73f856ab961cd2f79e36bc45d7ded33a7562adba4667aecc0e" -dependencies = [ - "proc-macro2", - "quote", - "serde_derive_internals", - "syn 2.0.77", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "security-framework" -version = "2.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" -dependencies = [ - "bitflags 2.6.0", - "core-foundation 0.9.4", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "semver" -version = "1.0.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" -dependencies = [ - "serde", -] - -[[package]] -name = "serde" -version = "1.0.209" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" -dependencies = [ - "serde_derive", + "futures-core", + "futures-sink", ] [[package]] -name = "serde-untagged" -version = "0.1.6" +name = "futures-core" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2676ba99bd82f75cae5cbd2c8eda6fa0b8760f18978ea840e980dd5567b5c5b6" -dependencies = [ - "erased-serde", - "serde", - "typeid", -] +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] -name = "serde-value" -version = "0.7.0" +name = "futures-executor" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ - "ordered-float", - "serde", + "futures-core", + "futures-task", + "futures-util", ] [[package]] -name = "serde_derive" -version = "1.0.209" +name = "futures-io" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] -name = "serde_derive_internals" -version = "0.29.1" +name = "futures-sink" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] -name = "serde_json" -version = "1.0.128" +name = "futures-task" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" -dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", -] +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] -name = "serde_repr" -version = "0.1.19" +name = "futures-util" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", ] [[package]] -name = "serde_spanned" -version = "0.6.7" +name = "generic-array" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ - "serde", + "typenum", + "version_check", ] [[package]] -name = "serde_urlencoded" -version = "0.7.1" +name = "glob" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" [[package]] -name = "serial_test" -version = "2.0.0" +name = "hashbrown" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e56dd856803e253c8f298af3f4d7eb0ae5e23a737252cd90bb4f3b435033b2d" -dependencies = [ - "dashmap 5.5.3", - "futures", - "lazy_static", - "log", - "parking_lot 0.12.3", - "serial_test_derive", -] +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] -name = "serial_test_derive" -version = "2.0.0" +name = "hashbrown" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] -name = "sha1" -version = "0.10.6" +name = "heck" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" dependencies = [ - "cfg-if 1.0.0", - "cpufeatures", - "digest", + "unicode-segmentation", ] [[package]] -name = "sha1_smol" -version = "1.0.1" +name = "heck" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] -name = "sha2" -version = "0.10.8" +name = "home" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" dependencies = [ - "cfg-if 1.0.0", - "cpufeatures", - "digest", + "windows-sys", ] [[package]] -name = "sha3" -version = "0.10.8" +name = "indexmap" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ - "digest", - "keccak", + "autocfg", + "hashbrown 0.12.3", ] [[package]] -name = "sharded-slab" -version = "0.1.7" +name = "indicatif" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +checksum = "2d207dc617c7a380ab07ff572a6e52fa202a2a8f355860ac9c38e23f8196be1b" dependencies = [ + "console", "lazy_static", + "number_prefix", + "regex", ] [[package]] -name = "shell-words" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "signal-hook" -version = "0.3.17" +name = "inotify" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +checksum = "4816c66d2c8ae673df83366c18341538f234a26d65a9ecea5c348b453ac1d02f" dependencies = [ + "bitflags 1.3.2", + "inotify-sys", "libc", - "signal-hook-registry", ] [[package]] -name = "signal-hook-registry" -version = "1.4.2" +name = "inotify-sys" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" dependencies = [ "libc", ] [[package]] -name = "siphasher" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" - -[[package]] -name = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] - -[[package]] -name = "smallvec" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" - -[[package]] -name = "smol_str" -version = "0.2.2" +name = "instant" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ - "serde", + "cfg-if 1.0.1", ] [[package]] -name = "socket2" -version = "0.5.7" +name = "iovec" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" dependencies = [ "libc", - "windows-sys 0.52.0", ] [[package]] -name = "spin" -version = "0.9.8" +name = "is_terminal_polyfill" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] -name = "sprs" -version = "0.7.1" +name = "itertools" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec63571489873d4506683915840eeb1bb16b3198ee4894cc6f2fe3013d505e56" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" dependencies = [ - "ndarray", - "num-complex", - "num-traits 0.1.43", + "either", ] [[package]] -name = "stable_deref_trait" -version = "1.2.0" +name = "itoa" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - -[[package]] -name = "starklings" -version = "0.1.0" -dependencies = [ - "anyhow", - "argh", - "ark-ff", - "ark-std 0.3.0", - "assert_cmd", - "cairo-lang-runner", - "cairo-lang-sierra", - "cairo-lang-test-plugin", - "cairo-lang-test-runner", - "camino", - "clap", - "colored", - "console", - "glob", - "home", - "indicatif 0.16.2", - "itertools 0.10.5", - "notify", - "num-bigint", - "num-traits 0.2.19", - "predicates", - "rayon 0.9.0", - "regex", - "salsa", - "scarb", - "scarb-ui", - "serde", - "serde_json", - "serial_test", - "thiserror", - "toml 0.5.11", - "unescaper", -] +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] -name = "starknet-crypto" -version = "0.6.2" +name = "kernel32-sys" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e2c30c01e8eb0fc913c4ee3cf676389fffc1d1182bfe5bb9670e4e72e968064" +checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" dependencies = [ - "crypto-bigint", - "hex", - "hmac", - "num-bigint", - "num-integer", - "num-traits 0.2.19", - "rfc6979", - "sha2", - "starknet-crypto-codegen", - "starknet-curve", - "starknet-ff", - "zeroize", + "winapi 0.2.8", + "winapi-build", ] [[package]] -name = "starknet-crypto-codegen" -version = "0.3.3" +name = "lazy_static" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbc159a1934c7be9761c237333a57febe060ace2bc9e3b337a59a37af206d19f" -dependencies = [ - "starknet-curve", - "starknet-ff", - "syn 2.0.77", -] +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] -name = "starknet-curve" -version = "0.4.2" +name = "lazycell" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1c383518bb312751e4be80f53e8644034aa99a0afb29d7ac41b89a997db875b" -dependencies = [ - "starknet-ff", -] +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] -name = "starknet-ff" -version = "0.3.7" +name = "libc" +version = "0.2.173" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7abf1b44ec5b18d87c1ae5f54590ca9d0699ef4dd5b2ffa66fc97f24613ec585" -dependencies = [ - "ark-ff", - "crypto-bigint", - "getrandom", - "hex", -] +checksum = "d8cfeafaffdbc32176b64fb251369d52ea9f0a8fbc6f8759edffef7b525d64bb" [[package]] -name = "starknet-types-core" -version = "0.1.5" +name = "libredox" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6bacf0ba19bc721e518bc4bf389ff13daa8a7c5db5fd320600473b8aa9fcbd" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "lambdaworks-crypto", - "lambdaworks-math", - "lazy_static", - "num-bigint", - "num-integer", - "num-traits 0.2.19", - "serde", + "bitflags 2.9.1", + "libc", + "redox_syscall 0.5.13", ] [[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "string_cache" -version = "0.8.7" +name = "lock_api" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" dependencies = [ - "new_debug_unreachable", - "once_cell", - "parking_lot 0.12.3", - "phf_shared", - "precomputed-hash", + "autocfg", + "scopeguard", ] [[package]] -name = "strsim" -version = "0.11.1" +name = "log" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] -name = "subtle" -version = "2.6.1" +name = "memchr" +version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] -name = "syn" -version = "1.0.109" +name = "mio" +version = "0.6.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", + "cfg-if 0.1.10", + "fuchsia-zircon", + "fuchsia-zircon-sys", + "iovec", + "kernel32-sys", + "libc", + "log", + "miow", + "net2", + "slab", + "winapi 0.2.8", ] [[package]] -name = "syn" -version = "2.0.77" +name = "mio-extras" +version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", + "lazycell", + "log", + "mio", + "slab", ] [[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - -[[package]] -name = "system-configuration" -version = "0.5.1" +name = "miow" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" dependencies = [ - "bitflags 1.3.2", - "core-foundation 0.9.4", - "system-configuration-sys", + "kernel32-sys", + "net2", + "winapi 0.2.8", + "ws2_32-sys", ] [[package]] -name = "system-configuration-sys" -version = "0.5.0" +name = "net2" +version = "0.2.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +checksum = "b13b648036a2339d06de780866fbdfda0dde886de7b3af2ddeba8b14f4ee34ac" dependencies = [ - "core-foundation-sys", + "cfg-if 0.1.10", "libc", + "winapi 0.3.9", ] [[package]] -name = "tap" -version = "1.0.1" +name = "normalize-line-endings" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" [[package]] -name = "tar" -version = "0.4.41" +name = "notify" +version = "4.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb797dad5fb5b76fcf519e702f4a589483b5ef06567f160c392832c1f5e44909" +checksum = "b72dd35279a5dc895a30965e247b0961ba36c233dc48454a2de8ccd459f1afd3" dependencies = [ + "bitflags 1.3.2", "filetime", + "fsevent", + "fsevent-sys", + "inotify", "libc", - "xattr", + "mio", + "mio-extras", + "walkdir", + "winapi 0.3.9", ] [[package]] -name = "tempfile" -version = "3.12.0" +name = "num-bigint" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ - "cfg-if 1.0.0", - "fastrand", - "once_cell", - "rustix", - "windows-sys 0.59.0", + "num-integer", + "num-traits", ] [[package]] -name = "term" -version = "0.7.0" +name = "num-integer" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "dirs-next", - "rustversion", - "winapi 0.3.9", + "num-traits", ] [[package]] -name = "termtree" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" - -[[package]] -name = "thiserror" -version = "1.0.63" +name = "num-traits" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ - "thiserror-impl", + "autocfg", ] [[package]] -name = "thiserror-impl" -version = "1.0.63" +name = "number_prefix" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] -name = "thiserror-impl-no-std" -version = "2.0.2" +name = "once_cell" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58e6318948b519ba6dc2b442a6d0b904ebfb8d411a3ad3e07843615a72249758" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] -name = "thiserror-no-std" -version = "2.0.2" +name = "once_cell_polyfill" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3ad459d94dd517257cc96add8a43190ee620011bb6e6cdc82dafd97dfafafea" -dependencies = [ - "thiserror-impl-no-std", -] +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" [[package]] -name = "thread_local" -version = "1.1.8" +name = "oorandom" +version = "11.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" -dependencies = [ - "cfg-if 1.0.0", - "once_cell", -] +checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" [[package]] -name = "time" -version = "0.3.36" +name = "parking_lot" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" dependencies = [ - "deranged", - "itoa", - "libc", - "num-conv", - "num_threads", - "powerfmt", - "serde", - "time-core", - "time-macros", + "instant", + "lock_api", + "parking_lot_core 0.8.6", ] [[package]] -name = "time-core" -version = "0.1.2" +name = "parking_lot" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +dependencies = [ + "lock_api", + "parking_lot_core 0.9.11", +] [[package]] -name = "time-macros" -version = "0.2.18" +name = "parking_lot_core" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" dependencies = [ - "num-conv", - "time-core", + "cfg-if 1.0.1", + "instant", + "libc", + "redox_syscall 0.2.16", + "smallvec", + "winapi 0.3.9", ] [[package]] -name = "tiny-keccak" -version = "2.0.2" +name = "parking_lot_core" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" dependencies = [ - "crunchy", + "cfg-if 1.0.1", + "libc", + "redox_syscall 0.5.13", + "smallvec", + "windows-targets", ] [[package]] -name = "tinyvec" -version = "1.8.0" +name = "paste" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" -dependencies = [ - "tinyvec_macros", -] +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] -name = "tinyvec_macros" -version = "0.1.1" +name = "pin-project-lite" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] -name = "tokio" -version = "1.40.0" +name = "pin-utils" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" -dependencies = [ - "backtrace", - "bytes", - "libc", - "mio 1.0.2", - "pin-project-lite", - "signal-hook-registry", - "socket2", - "tokio-macros", - "windows-sys 0.52.0", -] +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] -name = "tokio-macros" -version = "2.4.0" +name = "ppv-lite86" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", + "zerocopy", ] [[package]] -name = "tokio-native-tls" -version = "0.3.1" +name = "predicates" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +checksum = "f49cfaf7fdaa3bfacc6fa3e7054e65148878354a5cfddcf661df4c851f8021df" dependencies = [ - "native-tls", - "tokio", + "difference", + "float-cmp", + "normalize-line-endings", + "predicates-core", + "regex", ] [[package]] -name = "tokio-rustls" -version = "0.24.1" +name = "predicates-core" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" -dependencies = [ - "rustls", - "tokio", -] +checksum = "727e462b119fe9c93fd0eb1429a5f7647394014cf3c04ab2c0350eeb09095ffa" [[package]] -name = "tokio-util" -version = "0.7.12" +name = "predicates-tree" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" +checksum = "72dd2d6d381dfb73a193c7fca536518d7caee39fc8503f74e7dc0be0531b425c" dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", + "predicates-core", + "termtree", ] [[package]] -name = "toml" -version = "0.5.11" +name = "proc-macro2" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ - "serde", + "unicode-ident", ] [[package]] -name = "toml" -version = "0.8.19" +name = "quote" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", + "proc-macro2", ] [[package]] -name = "toml_datetime" -version = "0.6.8" +name = "rand" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ - "serde", + "rand_chacha", + "rand_core", ] [[package]] -name = "toml_edit" -version = "0.22.20" +name = "rand_chacha" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ - "indexmap 2.5.0", - "serde", - "serde_spanned", - "toml_datetime", - "winnow", + "ppv-lite86", + "rand_core", ] [[package]] -name = "tower-service" -version = "0.3.3" +name = "rand_core" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" [[package]] -name = "tracing" -version = "0.1.40" +name = "rayon" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "ed02d09394c94ffbdfdc755ad62a132e94c3224a8354e78a1200ced34df12edf" dependencies = [ - "pin-project-lite", - "tracing-attributes", - "tracing-core", + "either", + "rayon-core", ] [[package]] -name = "tracing-attributes" -version = "0.1.27" +name = "rayon-core" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", + "crossbeam-deque", + "crossbeam-utils", ] [[package]] -name = "tracing-core" -version = "0.1.32" +name = "redox_syscall" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ - "once_cell", - "valuable", + "bitflags 1.3.2", ] [[package]] -name = "tracing-log" -version = "0.2.0" +name = "redox_syscall" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6" dependencies = [ - "log", - "once_cell", - "tracing-core", + "bitflags 2.9.1", ] [[package]] -name = "tracing-subscriber" -version = "0.3.18" +name = "regex" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ - "matchers", - "nu-ansi-term", - "once_cell", - "regex", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", ] [[package]] -name = "triomphe" -version = "0.1.13" +name = "regex-automata" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6631e42e10b40c0690bf92f404ebcfe6e1fdb480391d15f17cc8e96eeed5369" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ - "serde", - "stable_deref_trait", + "aho-corasick", + "memchr", + "regex-syntax", ] [[package]] -name = "try-lock" -version = "0.2.5" +name = "regex-syntax" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] -name = "typed-builder" -version = "0.20.0" +name = "rust-fuzzy-search" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e14ed59dc8b7b26cacb2a92bad2e8b1f098806063898ab42a3bd121d7d45e75" -dependencies = [ - "typed-builder-macro", -] +checksum = "a157657054ffe556d8858504af8a672a054a6e0bd9e8ee531059100c0fa11bb2" [[package]] -name = "typed-builder-macro" -version = "0.20.0" +name = "rustc-hash" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "560b82d656506509d43abe30e0ba64c56b1953ab3d4fe7ba5902747a7a3cedd5" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] -name = "typeid" -version = "1.0.2" +name = "rustc_version" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e13db2e0ccd5e14a544e8a246ba2312cd25223f616442d7f2cb0e3db614236e" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] [[package]] -name = "typenum" -version = "1.17.0" +name = "ryu" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] -name = "uluru" -version = "3.1.0" +name = "salsa" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c8a2469e56e6e5095c82ccd3afb98dad95f7af7929aab6d8ba8d6e0f73657da" +checksum = "4b84d9f96071f3f3be0dc818eae3327625d8ebc95b58da37d6850724f31d3403" dependencies = [ - "arrayvec", + "crossbeam-utils", + "indexmap", + "lock_api", + "log", + "oorandom", + "parking_lot 0.11.2", + "rustc-hash", + "salsa-macros", + "smallvec", ] [[package]] -name = "unescaper" -version = "0.1.5" +name = "salsa-macros" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c878a167baa8afd137494101a688ef8c67125089ff2249284bd2b5f9bfedb815" +checksum = "cd3904a4ba0a9d0211816177fd34b04c7095443f8cdacd11175064fe541c8fe2" dependencies = [ - "thiserror", + "heck 0.3.3", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] -name = "unicase" -version = "2.7.0" +name = "same-file" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" dependencies = [ - "version_check", + "winapi-util", ] [[package]] -name = "unicode-bidi" -version = "0.3.15" +name = "scopeguard" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] -name = "unicode-bom" -version = "2.0.3" +name = "semver" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eec5d1121208364f6793f7d2e222bf75a915c19557537745b195b253dd64217" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" [[package]] -name = "unicode-ident" -version = "1.0.12" +name = "serde" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.103", +] [[package]] -name = "unicode-normalization" -version = "0.1.23" +name = "serde_json" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ - "tinyvec", + "itoa", + "memchr", + "ryu", + "serde", ] [[package]] -name = "unicode-segmentation" -version = "1.11.0" +name = "serial_test" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +checksum = "0e56dd856803e253c8f298af3f4d7eb0ae5e23a737252cd90bb4f3b435033b2d" +dependencies = [ + "dashmap", + "futures", + "lazy_static", + "log", + "parking_lot 0.12.4", + "serial_test_derive", +] [[package]] -name = "unicode-width" -version = "0.1.13" +name = "serial_test_derive" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" +checksum = "91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.103", +] [[package]] -name = "unicode-xid" -version = "0.2.5" +name = "slab" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a" +checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" [[package]] -name = "untrusted" -version = "0.9.0" +name = "smallvec" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] -name = "url" -version = "2.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +name = "starklings" +version = "0.1.0" dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", + "anyhow", + "argh", + "ark-ff", + "ark-std 0.3.0", + "assert_cmd", + "camino", + "clap", + "colored", + "console", + "glob", + "home", + "indicatif", + "itertools", + "notify", + "num-bigint", + "num-traits", + "predicates", + "rayon", + "regex", + "salsa", "serde", + "serde_json", + "serial_test", + "thiserror 1.0.69", + "toml", + "unescaper", ] [[package]] -name = "utf8parse" -version = "0.2.2" +name = "strsim" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] -name = "valuable" -version = "0.1.0" +name = "syn" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] [[package]] -name = "vcpkg" -version = "0.2.15" +name = "syn" +version = "2.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +checksum = "e4307e30089d6fd6aff212f2da3a1f9e32f3223b1f010fb09b7c95f90f3ca1e8" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] [[package]] -name = "version_check" -version = "0.9.5" +name = "termtree" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" [[package]] -name = "walkdir" -version = "2.5.0" +name = "thiserror" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "same-file", - "winapi-util", + "thiserror-impl 1.0.69", ] [[package]] -name = "want" -version = "0.3.1" +name = "thiserror" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" dependencies = [ - "try-lock", + "thiserror-impl 2.0.12", ] [[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.93" +name = "thiserror-impl" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ - "cfg-if 1.0.0", - "once_cell", - "wasm-bindgen-macro", + "proc-macro2", + "quote", + "syn 2.0.103", ] [[package]] -name = "wasm-bindgen-backend" -version = "0.2.93" +name = "thiserror-impl" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ - "bumpalo", - "log", - "once_cell", "proc-macro2", "quote", - "syn 2.0.77", - "wasm-bindgen-shared", + "syn 2.0.103", ] [[package]] -name = "wasm-bindgen-futures" -version = "0.4.43" +name = "toml" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" dependencies = [ - "cfg-if 1.0.0", - "js-sys", - "wasm-bindgen", - "web-sys", + "serde", ] [[package]] -name = "wasm-bindgen-macro" -version = "0.2.93" +name = "typenum" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" [[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.93" +name = "unescaper" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +checksum = "c01d12e3a56a4432a8b436f293c25f4808bdf9e9f9f98f9260bba1f1bc5a1f26" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", - "wasm-bindgen-backend", - "wasm-bindgen-shared", + "thiserror 2.0.12", ] [[package]] -name = "wasm-bindgen-shared" -version = "0.2.93" +name = "unicode-ident" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] -name = "wasm-streams" -version = "0.4.0" +name = "unicode-segmentation" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129" -dependencies = [ - "futures-util", - "js-sys", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] -name = "web-sys" -version = "0.3.70" +name = "unicode-width" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" -dependencies = [ - "js-sys", - "wasm-bindgen", -] +checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] -name = "which" -version = "5.0.0" +name = "walkdir" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bf3ea8596f3a0dd5980b46430f2058dfe2c36a27ccfbb1845d6fbfcd9ba6e14" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ - "either", - "home", - "once_cell", - "rustix", - "windows-sys 0.48.0", + "same-file", + "winapi-util", ] [[package]] @@ -5951,7 +1410,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.59.0", + "windows-sys", ] [[package]] @@ -5960,46 +1419,13 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.6", -] - [[package]] name = "windows-sys" version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", + "windows-targets", ] [[package]] @@ -6008,46 +1434,28 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -6060,73 +1468,30 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "winnow" -version = "0.6.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" -dependencies = [ - "memchr", -] - -[[package]] -name = "winreg" -version = "0.50.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" -dependencies = [ - "cfg-if 1.0.0", - "windows-sys 0.48.0", -] - [[package]] name = "ws2_32-sys" version = "0.2.1" @@ -6137,72 +1502,24 @@ dependencies = [ "winapi-build", ] -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - -[[package]] -name = "xattr" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" -dependencies = [ - "libc", - "linux-raw-sys", - "rustix", -] - -[[package]] -name = "xshell" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db0ab86eae739efd1b054a8d3d16041914030ac4e01cd1dca0cf252fd8b6437" -dependencies = [ - "xshell-macros", -] - -[[package]] -name = "xshell-macros" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d422e8e38ec76e2f06ee439ccc765e9c6a9638b9e7c9f2e8255e4d41e8bd852" - -[[package]] -name = "xxhash-rust" -version = "0.8.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a5cbf750400958819fb6178eaa83bee5cd9c29a26a40cc241df8c70fdd46984" - -[[package]] -name = "yansi" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" - [[package]] name = "zerocopy" -version = "0.7.35" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" dependencies = [ - "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.35" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.103", ] [[package]] @@ -6222,72 +1539,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", -] - -[[package]] -name = "zip" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" -dependencies = [ - "aes", - "byteorder", - "bzip2", - "constant_time_eq", - "crc32fast", - "crossbeam-utils", - "flate2", - "hmac", - "pbkdf2", - "sha1", - "time", - "zstd 0.11.2+zstd.1.5.2", -] - -[[package]] -name = "zstd" -version = "0.11.2+zstd.1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" -dependencies = [ - "zstd-safe 5.0.2+zstd.1.5.2", -] - -[[package]] -name = "zstd" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" -dependencies = [ - "zstd-safe 7.2.1", -] - -[[package]] -name = "zstd-safe" -version = "5.0.2+zstd.1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" -dependencies = [ - "libc", - "zstd-sys", -] - -[[package]] -name = "zstd-safe" -version = "7.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" -dependencies = [ - "zstd-sys", -] - -[[package]] -name = "zstd-sys" -version = "2.0.13+zstd.1.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" -dependencies = [ - "cc", - "pkg-config", + "syn 2.0.103", ] diff --git a/Cargo.toml b/Cargo.toml index 212af3ce8..8d1f80804 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,14 +22,6 @@ serde_json = "1.0.81" home = "0.5.3" glob = "0.3.0" -# Cairo runner dependencies -cairo-lang-test-runner = "2.8.2" -cairo-lang-test-plugin = "2.8.2" -cairo-lang-runner = "2.8.2" -cairo-lang-sierra = "2.8.2" -scarb = { git = "https://github.com/software-mansion/scarb", tag = "v2.8.2" } -scarb-ui = { git = "https://github.com/software-mansion/scarb", tag = "v2.8.2" } - anyhow = "1.0.66" ark-ff = "0.4.0-alpha.7" ark-std = "0.3.0" diff --git a/README.md b/README.md index 8e714cf2d..797d775ab 100755 --- a/README.md +++ b/README.md @@ -34,6 +34,13 @@ CLI-based interactive tutorial #### Both versions share the same core exercises and hints, with a single source of truth for all content. +## Requirements + +You'll need to have Scarb and Starknet Foundry installed. You can do this with a single CLI command, using [Starkup](https://github.com/software-mansion/starkup): +``` +curl --proto '=https' --tlsv1.2 -sSf https://sh.starkup.sh | sh +``` + ## Contributing Thanks for your interest in the project. You can fork the repo, create a branch with a descriptive name (maybe the issue number and a word or two to describe it) and submit a pull request. diff --git a/Scarb.lock b/Scarb.lock new file mode 100644 index 000000000..594a8c539 --- /dev/null +++ b/Scarb.lock @@ -0,0 +1,24 @@ +# Code generated by scarb DO NOT EDIT. +version = 1 + +[[package]] +name = "snforge_scarb_plugin" +version = "0.44.0" +source = "registry+https://scarbs.xyz/" +checksum = "sha256:ec8c7637b33392a53153c1e5b87a4617ddcb1981951b233ea043cad5136697e2" + +[[package]] +name = "snforge_std" +version = "0.44.0" +source = "registry+https://scarbs.xyz/" +checksum = "sha256:d4affedfb90715b1ac417b915c0a63377ae6dd69432040e5d933130d65114702" +dependencies = [ + "snforge_scarb_plugin", +] + +[[package]] +name = "starklings_cairo1" +version = "0.1.0" +dependencies = [ + "snforge_std", +] diff --git a/corelib/Scarb.toml b/corelib/Scarb.toml deleted file mode 100644 index 903aa842c..000000000 --- a/corelib/Scarb.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "core" -version = "2.6.3" -edition = "2023_11" -experimental-features = ["coupons", "negative_impls"] - -# NOTE: This is non-public, unstable Scarb's field, which instructs resolver that this package does not -# depend on `core`, which is only true for this particular package. Nobody else should use it. -no-core = true diff --git a/corelib/cairo_project.toml b/corelib/cairo_project.toml deleted file mode 100644 index 8d5e456cf..000000000 --- a/corelib/cairo_project.toml +++ /dev/null @@ -1,9 +0,0 @@ -[crate_roots] -core = "src" - -[config.global] -edition = "2023_11" - -[config.global.experimental_features] -negative_impls = true -coupons = true diff --git a/corelib/src/array.cairo b/corelib/src/array.cairo deleted file mode 100644 index 4924fb2ba..000000000 --- a/corelib/src/array.cairo +++ /dev/null @@ -1,270 +0,0 @@ -use core::traits::IndexView; - -use core::box::BoxTrait; -use core::gas::withdraw_gas; -use core::option::OptionTrait; -use core::serde::Serde; -use core::metaprogramming::TypeEqual; - -#[derive(Drop)] -pub extern type Array; - -extern fn array_new() -> Array nopanic; -extern fn array_append(ref arr: Array, value: T) nopanic; -extern fn array_pop_front(ref arr: Array) -> Option> nopanic; -extern fn array_pop_front_consume(arr: Array) -> Option<(Array, Box)> nopanic; -pub(crate) extern fn array_snapshot_pop_front(ref arr: @Array) -> Option> nopanic; -extern fn array_snapshot_pop_back(ref arr: @Array) -> Option> nopanic; -#[panic_with('Index out of bounds', array_at)] -extern fn array_get( - arr: @Array, index: usize -) -> Option> implicits(RangeCheck) nopanic; -extern fn array_slice( - arr: @Array, start: usize, length: usize -) -> Option<@Array> implicits(RangeCheck) nopanic; -extern fn array_len(arr: @Array) -> usize nopanic; - -#[generate_trait] -pub impl ArrayImpl of ArrayTrait { - #[inline(always)] - fn new() -> Array nopanic { - array_new() - } - #[inline(always)] - fn append(ref self: Array, value: T) nopanic { - array_append(ref self, value) - } - fn append_span<+Clone, +Drop>(ref self: Array, mut span: Span) { - match span.pop_front() { - Option::Some(current) => { - self.append(current.clone()); - self.append_span(span); - }, - Option::None => {} - }; - } - #[inline(always)] - fn pop_front(ref self: Array) -> Option nopanic { - match array_pop_front(ref self) { - Option::Some(x) => Option::Some(x.unbox()), - Option::None => Option::None, - } - } - #[inline(always)] - fn pop_front_consume(self: Array) -> Option<(Array, T)> nopanic { - match array_pop_front_consume(self) { - Option::Some((arr, x)) => Option::Some((arr, x.unbox())), - Option::None => Option::None, - } - } - #[inline(always)] - fn get(self: @Array, index: usize) -> Option> { - array_get(self, index) - } - fn at(self: @Array, index: usize) -> @T { - array_at(self, index).unbox() - } - #[inline(always)] - #[must_use] - fn len(self: @Array) -> usize { - array_len(self) - } - #[inline(always)] - #[must_use] - fn is_empty(self: @Array) -> bool { - let mut snapshot = self; - match array_snapshot_pop_front(ref snapshot) { - Option::Some(_) => false, - Option::None => true, - } - } - #[inline(always)] - #[must_use] - fn span(self: @Array) -> Span { - Span { snapshot: self } - } -} - -impl ArrayDefault of Default> { - #[inline(always)] - fn default() -> Array { - ArrayTrait::new() - } -} - -impl ArrayIndex of IndexView, usize, @T> { - fn index(self: @Array, index: usize) -> @T { - array_at(self, index).unbox() - } -} - -impl ArraySerde, +Drop> of Serde> { - fn serialize(self: @Array, ref output: Array) { - self.len().serialize(ref output); - serialize_array_helper(self.span(), ref output); - } - fn deserialize(ref serialized: Span) -> Option> { - let length = *serialized.pop_front()?; - let mut arr = array![]; - deserialize_array_helper(ref serialized, arr, length) - } -} - -fn serialize_array_helper, +Drop>(mut input: Span, ref output: Array) { - match input.pop_front() { - Option::Some(value) => { - value.serialize(ref output); - serialize_array_helper(input, ref output); - }, - Option::None => {}, - } -} - -fn deserialize_array_helper, +Drop>( - ref serialized: Span, mut curr_output: Array, remaining: felt252 -) -> Option> { - if remaining == 0 { - return Option::Some(curr_output); - } - curr_output.append(Serde::deserialize(ref serialized)?); - deserialize_array_helper(ref serialized, curr_output, remaining - 1) -} - -// Span. -pub struct Span { - pub(crate) snapshot: @Array -} - -impl SpanCopy of Copy>; -impl SpanDrop of Drop>; - -impl SpanFelt252Serde of Serde> { - fn serialize(self: @Span, ref output: Array) { - (*self).len().serialize(ref output); - serialize_array_helper(*self, ref output) - } - - fn deserialize(ref serialized: Span) -> Option> { - let length: u32 = (*serialized.pop_front()?).try_into()?; - let res = serialized.slice(0, length); - serialized = serialized.slice(length, serialized.len() - length); - Option::Some(res) - } -} - -impl SpanSerde, +Drop, -TypeEqual> of Serde> { - fn serialize(self: @Span, ref output: Array) { - (*self).len().serialize(ref output); - serialize_array_helper(*self, ref output) - } - - fn deserialize(ref serialized: Span) -> Option> { - let length = *serialized.pop_front()?; - let mut arr = array_new(); - Option::Some(deserialize_array_helper(ref serialized, arr, length)?.span()) - } -} - -#[generate_trait] -pub impl SpanImpl of SpanTrait { - #[inline(always)] - fn pop_front(ref self: Span) -> Option<@T> { - let mut snapshot = self.snapshot; - let item = array_snapshot_pop_front(ref snapshot); - self = Span { snapshot }; - match item { - Option::Some(x) => Option::Some(x.unbox()), - Option::None => Option::None, - } - } - #[inline(always)] - fn pop_back(ref self: Span) -> Option<@T> { - let mut snapshot = self.snapshot; - let item = array_snapshot_pop_back(ref snapshot); - self = Span { snapshot }; - match item { - Option::Some(x) => Option::Some(x.unbox()), - Option::None => Option::None, - } - } - #[inline(always)] - fn get(self: Span, index: usize) -> Option> { - array_get(self.snapshot, index) - } - #[inline(always)] - fn at(self: Span, index: usize) -> @T { - array_at(self.snapshot, index).unbox() - } - #[inline(always)] - fn slice(self: Span, start: usize, length: usize) -> Span { - Span { snapshot: array_slice(self.snapshot, start, length).expect('Index out of bounds') } - } - #[inline(always)] - #[must_use] - fn len(self: Span) -> usize { - array_len(self.snapshot) - } - #[inline(always)] - #[must_use] - fn is_empty(self: Span) -> bool { - let mut snapshot = self.snapshot; - match array_snapshot_pop_front(ref snapshot) { - Option::Some(_) => false, - Option::None => true, - } - } -} - -pub impl SpanIndex of IndexView, usize, @T> { - #[inline(always)] - fn index(self: @Span, index: usize) -> @T { - array_at(*self.snapshot, index).unbox() - } -} - -// TODO(spapini): Remove TDrop. It is necessary to get rid of response in case of panic. -impl ArrayTCloneImpl, +Drop> of Clone> { - fn clone(self: @Array) -> Array { - let mut response = array_new(); - let mut span = self.span(); - loop { - match span.pop_front() { - Option::Some(v) => { response.append(v.clone()); }, - Option::None => { break (); }, - }; - }; - response - } -} - -impl ArrayPartialEq> of PartialEq> { - fn eq(lhs: @Array, rhs: @Array) -> bool { - lhs.span() == rhs.span() - } - fn ne(lhs: @Array, rhs: @Array) -> bool { - !(lhs == rhs) - } -} - -impl SpanPartialEq> of PartialEq> { - fn eq(lhs: @Span, rhs: @Span) -> bool { - if (*lhs).len() != (*rhs).len() { - return false; - } - let mut lhs_span = *lhs; - let mut rhs_span = *rhs; - loop { - match lhs_span.pop_front() { - Option::Some(lhs_v) => { - if lhs_v != rhs_span.pop_front().unwrap() { - break false; - } - }, - Option::None => { break true; }, - }; - } - } - fn ne(lhs: @Span, rhs: @Span) -> bool { - !(lhs == rhs) - } -} diff --git a/corelib/src/boolean.cairo b/corelib/src/boolean.cairo deleted file mode 100644 index f51efba4d..000000000 --- a/corelib/src/boolean.cairo +++ /dev/null @@ -1,19 +0,0 @@ -#[generate_trait] -pub impl BoolImpl> of BoolTrait { - /// Returns `Some(t)` if the `bool` is `true`, or `None` otherwise. - /// - /// # Examples - /// - /// ``` - /// assert(false.then_some(0) == Option::None); - /// assert(true.then_some(0) == Option::Some(0)); - /// ``` - #[inline(always)] - fn then_some(self: bool, t: T) -> Option nopanic { - if self { - Option::Some(t) - } else { - Option::None - } - } -} diff --git a/corelib/src/box.cairo b/corelib/src/box.cairo deleted file mode 100644 index 706bdaa7d..000000000 --- a/corelib/src/box.cairo +++ /dev/null @@ -1,34 +0,0 @@ -#[derive(Copy, Drop)] -pub extern type Box; - -// These functions are only exposed in the corelib through the trait below since calling them -// directly with tuples panics due to auto unpacking of the tuple. -// TODO(Gil): Expose in the core lib when the described behaviour is fixed. -extern fn into_box(value: T) -> Box nopanic; -extern fn unbox(box: Box) -> T nopanic; -extern fn box_forward_snapshot(value: @Box) -> Box<@T> nopanic; - -#[generate_trait] -pub impl BoxImpl of BoxTrait { - #[inline(always)] - #[must_use] - fn new(value: T) -> Box nopanic { - into_box(value) - } - #[inline(always)] - #[must_use] - fn unbox(self: Box) -> T nopanic { - unbox(self) - } - #[must_use] - fn as_snapshot(self: @Box) -> Box<@T> nopanic { - box_forward_snapshot(self) - } -} - -impl BoxDebug> of core::fmt::Debug> { - fn fmt(self: @Box, ref f: core::fmt::Formatter) -> Result<(), core::fmt::Error> { - write!(f, "&")?; - TDebug::fmt(self.as_snapshot().unbox(), ref f) - } -} diff --git a/corelib/src/byte_array.cairo b/corelib/src/byte_array.cairo deleted file mode 100644 index 43379f157..000000000 --- a/corelib/src/byte_array.cairo +++ /dev/null @@ -1,361 +0,0 @@ -use core::array::{ArrayTrait, SpanTrait}; -use core::bytes_31::{ - BYTES_IN_BYTES31, Bytes31Trait, one_shift_left_bytes_felt252, one_shift_left_bytes_u128, - POW_2_128, POW_2_8, U128IntoBytes31, U8IntoBytes31 -}; -use core::clone::Clone; -use core::cmp::min; -use core::integer::{u128_safe_divmod, U32TryIntoNonZero}; -use core::option::OptionTrait; -use core::traits::{Into, TryInto}; -use core::serde::Serde; -use core::zeroable::NonZeroIntoImpl; - -/// A magic constant for identifying serialization of ByteArrays. An array of felt252s with this -/// magic as one of the felt252s indicates that right after it you should expect a serialized -/// ByteArray. This is currently used mainly for prints and panics. -pub(crate) const BYTE_ARRAY_MAGIC: felt252 = - 0x46a6158a16a947e5916b2a2ca68501a45e93d7110e81aa2d6438b1c57c879a3; -const BYTES_IN_U128: usize = 16; -const BYTES_IN_BYTES31_MINUS_ONE: usize = BYTES_IN_BYTES31 - 1; - -// TODO(yuval): don't allow creation of invalid ByteArray? -#[derive(Drop, Clone, PartialEq, Serde, Default)] -pub struct ByteArray { - // Full "words" of 31 bytes each. The first byte of each word in the byte array - // is the most significant byte in the word. - pub(crate) data: Array, - // This felt252 actually represents a bytes31, with < 31 bytes. - // It is represented as a felt252 to improve performance of building the byte array. - // The number of bytes in here is specified in `pending_word_len`. - // The first byte is the most significant byte among the `pending_word_len` bytes in the word. - pub(crate) pending_word: felt252, - // Should be in range [0, 30]. - pub(crate) pending_word_len: usize, -} - -pub(crate) impl ByteArrayStringLiteral of core::string::StringLiteral; - -#[generate_trait] -pub impl ByteArrayImpl of ByteArrayTrait { - // TODO(yuval): add a `new` function for initialization. - - // Appends a single word of `len` bytes to the end of the ByteArray. - // Note: this function assumes that: - // 1. `word` could be validly converted to a `bytes31` which has no more than `len` bytes - // of data. - // 2. len <= BYTES_IN_BYTES31. - // If these assumptions are not met, it can corrupt the ByteArray. Thus, this should be a - // private function. We could add masking/assertions but it would be more expensive. - fn append_word(ref self: ByteArray, word: felt252, len: usize) { - if len == 0 { - return; - } - let total_pending_bytes = self.pending_word_len + len; - - if total_pending_bytes < BYTES_IN_BYTES31 { - self.append_word_fits_into_pending(word, len); - return; - } - - if total_pending_bytes == BYTES_IN_BYTES31 { - self - .data - .append( - (word + self.pending_word * one_shift_left_bytes_felt252(len)) - .try_into() - .unwrap() - ); - self.pending_word = 0; - self.pending_word_len = 0; - return; - } - - // The split index is the number of bytes left for the next word (new pending_word of the - // modified ByteArray). - let split_index = total_pending_bytes - BYTES_IN_BYTES31; - if split_index == BYTES_IN_U128 { - self.append_split_index_16(word); - } else if split_index < BYTES_IN_U128 { - self.append_split_index_lt_16(word, split_index); - } else { // split_index > BYTES_IN_U128 - self.append_split_index_gt_16(word, split_index); - } - self.pending_word_len = split_index; - } - - // Appends a byte array to the end of `self`. - fn append(ref self: ByteArray, mut other: @ByteArray) { - let mut other_data = other.data.span(); - - if self.pending_word_len == 0 { - self.data.append_span(other_data); - self.pending_word = *other.pending_word; - self.pending_word_len = *other.pending_word_len; - return; - } - - // self.pending_word_len is in [1, 30]. This is the split index for all the full words of - // `other`, as for each word, this is the number of bytes left for the next word. - if self.pending_word_len == BYTES_IN_U128 { - loop { - match other_data.pop_front() { - Option::Some(current_word) => { - self.append_split_index_16((*current_word).into()); - }, - Option::None => { break; } - }; - }; - } else if self.pending_word_len < BYTES_IN_U128 { - loop { - match other_data.pop_front() { - Option::Some(current_word) => { - self - .append_split_index_lt_16( - (*current_word).into(), self.pending_word_len - ); - }, - Option::None => { break; } - }; - }; - } else { - // self.pending_word_len > BYTES_IN_U128 - loop { - match other_data.pop_front() { - Option::Some(current_word) => { - self - .append_split_index_gt_16( - (*current_word).into(), self.pending_word_len - ); - }, - Option::None => { break; } - }; - }; - } - - // Add the pending word of `other`. - self.append_word(*other.pending_word, *other.pending_word_len); - } - - // Concatenates two byte arrays and returns the result. - fn concat(left: @ByteArray, right: @ByteArray) -> ByteArray { - let mut result = left.clone(); - result.append(right); - result - } - - // Appends a single byte to the end of `self`. - fn append_byte(ref self: ByteArray, byte: u8) { - if self.pending_word_len == 0 { - self.pending_word = byte.into(); - self.pending_word_len = 1; - return; - } - - let new_pending = self.pending_word * POW_2_8.into() + byte.into(); - - if self.pending_word_len != BYTES_IN_BYTES31_MINUS_ONE { - self.pending_word = new_pending; - self.pending_word_len += 1; - return; - } - - // self.pending_word_len == 30 - self.data.append(new_pending.try_into().unwrap()); - self.pending_word = 0; - self.pending_word_len = 0; - } - - #[must_use] - fn len(self: @ByteArray) -> usize { - self.data.len() * BYTES_IN_BYTES31.into() + (*self.pending_word_len).into() - } - - // Returns the byte at the given index, or None if the index is out of bounds. - fn at(self: @ByteArray, index: usize) -> Option { - let (word_index, index_in_word) = DivRem::div_rem( - index, BYTES_IN_BYTES31.try_into().unwrap() - ); - - let data_len = self.data.len(); - if word_index == data_len { - // Index is in pending word. - if index_in_word >= *self.pending_word_len { - return Option::None; - } - // index_in_word is from MSB, we need index from LSB. - let index_from_lsb = *self.pending_word_len - 1 - index_in_word; - let pending_bytes31: bytes31 = (*self.pending_word).try_into().unwrap(); - return Option::Some(pending_bytes31.at(index_from_lsb)); - } - - if word_index > data_len { - return Option::None; - } - - // index_in_word is from MSB, we need index from LSB. - let index_from_lsb = BYTES_IN_BYTES31 - 1 - index_in_word; - Option::Some(self.data.at(word_index).at(index_from_lsb)) - } - - /// Returns a ByteArray with the reverse order of `self`. - fn rev(self: @ByteArray) -> ByteArray { - let mut result = Default::default(); - - result.append_word_rev(*self.pending_word, *self.pending_word_len); - - let mut data = self.data.span(); - loop { - match data.pop_back() { - Option::Some(current_word) => { - result.append_word_rev((*current_word).into(), BYTES_IN_BYTES31); - }, - Option::None => { break; } - }; - }; - result - } - - /// Appends the reverse of the given word to the end `self`. - /// Assumptions: - /// 1. len < 31 - /// 2. word is validly convertible to bytes31 of length `len`. - fn append_word_rev(ref self: ByteArray, word: felt252, len: usize) { - let mut index = 0; - - let u256 { low, high } = word.into(); - let low_part_limit = min(len, BYTES_IN_U128); - loop { - if index == low_part_limit { - break; - } - let curr_byte_as_u128 = (low / one_shift_left_bytes_u128(index)) % POW_2_8; - - self.append_byte(curr_byte_as_u128.try_into().unwrap()); - index += 1; - }; - if low_part_limit == BYTES_IN_U128 { - let mut index_in_high_part = 0; - let high_part_len = len - BYTES_IN_U128; - loop { - if index_in_high_part == high_part_len { - break; - } - let curr_byte_as_u128 = (high - / one_shift_left_bytes_u128(index_in_high_part)) % POW_2_8; - - self.append_byte(curr_byte_as_u128.try_into().unwrap()); - index_in_high_part += 1; - } - } - } - - // === Helpers === - - // Appends a single word of `len` bytes to the end of the ByteArray, assuming there - // is enough space in the pending word (`self.pending_word_len + len < BYTES_IN_BYTES31`). - // - // `word` is of type felt252 but actually represents a bytes31. - // It is represented as a felt252 to improve performance of building the byte array. - #[inline] - fn append_word_fits_into_pending(ref self: ByteArray, word: felt252, len: usize) { - if self.pending_word_len == 0 { - // len < BYTES_IN_BYTES31 - self.pending_word = word; - self.pending_word_len = len; - return; - } - - self.pending_word = word + self.pending_word * one_shift_left_bytes_felt252(len); - self.pending_word_len += len; - } - - // Appends a single word to the end of `self`, given that `0 < split_index < 16`. - // - // `split_index` is the number of bytes left in `self.pending_word` after this function. This is - // the index of the split (LSB's index is 0). - // - // Note: this function doesn't update the new pending length of self. It's the caller's - // responsibility. - #[inline] - fn append_split_index_lt_16(ref self: ByteArray, word: felt252, split_index: usize) { - let u256 { low, high } = word.into(); - - let (low_quotient, low_remainder) = u128_safe_divmod( - low, one_shift_left_bytes_u128(split_index).try_into().unwrap() - ); - let left = high.into() * one_shift_left_bytes_u128(BYTES_IN_U128 - split_index).into() - + low_quotient.into(); - - self.append_split(left, low_remainder.into()); - } - - // Appends a single word to the end of `self`, given that the index of splitting `word` is - // exactly 16. - // - // `split_index` is the number of bytes left in `self.pending_word` after this function. This is - // the index of the split (LSB's index is 0). - // - // Note: this function doesn't update the new pending length of self. It's the caller's - // responsibility. - #[inline] - fn append_split_index_16(ref self: ByteArray, word: felt252) { - let u256 { low, high } = word.into(); - self.append_split(high.into(), low.into()); - } - - // Appends a single word to the end of `self`, given that the index of splitting `word` is > 16. - // - // `split_index` is the number of bytes left in `self.pending_word` after this function. This is - // the index of the split (LSB's index is 0). - // - // Note: this function doesn't update the new pending length of self. It's the caller's - // responsibility. - #[inline] - fn append_split_index_gt_16(ref self: ByteArray, word: felt252, split_index: usize) { - let u256 { low, high } = word.into(); - - let (high_quotient, high_remainder) = u128_safe_divmod( - high, one_shift_left_bytes_u128(split_index - BYTES_IN_U128).try_into().unwrap() - ); - let right = high_remainder.into() * POW_2_128 + low.into(); - - self.append_split(high_quotient.into(), right); - } - - // A helper function to append a remainder to self, by: - // 1. completing `self.pending_word` to a full word using `complete_full_word`, assuming it's - // validly convertible to a `bytes31` of length exactly `BYTES_IN_BYTES31 - - // self.pending_word_len`. - // 2. Setting `self.pending_word` to `new_pending`. - // - // Note: this function doesn't update the new pending length of self. It's the caller's - // responsibility. - #[inline] - fn append_split(ref self: ByteArray, complete_full_word: felt252, new_pending: felt252) { - let to_append = complete_full_word - + self.pending_word - * one_shift_left_bytes_felt252(BYTES_IN_BYTES31 - self.pending_word_len); - self.data.append(to_append.try_into().unwrap()); - self.pending_word = new_pending; - } -} - -impl ByteArrayAdd of Add { - #[inline] - fn add(lhs: ByteArray, rhs: ByteArray) -> ByteArray { - ByteArrayTrait::concat(@lhs, @rhs) - } -} -impl ByteArrayAddEq of AddEq { - #[inline] - fn add_eq(ref self: ByteArray, other: ByteArray) { - self.append(@other); - } -} - -pub(crate) impl ByteArrayIndexView of IndexView { - fn index(self: @ByteArray, index: usize) -> u8 { - self.at(index).expect('Index out of bounds') - } -} diff --git a/corelib/src/bytes_31.cairo b/corelib/src/bytes_31.cairo deleted file mode 100644 index 840282d07..000000000 --- a/corelib/src/bytes_31.cairo +++ /dev/null @@ -1,186 +0,0 @@ -use core::traits::{Into, TryInto}; -use core::option::OptionTrait; -use core::integer::{u128_safe_divmod, u128_to_felt252}; - -pub(crate) const BYTES_IN_BYTES31: usize = 31; -const BYTES_IN_U128: usize = 16; -pub(crate) const POW_2_128: felt252 = 0x100000000000000000000000000000000; -pub(crate) const POW_2_8: u128 = 0x100; - -#[derive(Copy, Drop)] -pub extern type bytes31; - -pub(crate) extern fn bytes31_const() -> bytes31 nopanic; -extern fn bytes31_try_from_felt252(value: felt252) -> Option implicits(RangeCheck) nopanic; -extern fn bytes31_to_felt252(value: bytes31) -> felt252 nopanic; - -#[generate_trait] -pub impl Bytes31Impl of Bytes31Trait { - // Gets the byte at the given index (LSB's index is 0), assuming that - // `index < BYTES_IN_BYTES31`. If the assumption is not met, the behavior is undefined. - fn at(self: @bytes31, index: usize) -> u8 { - let u256 { low, high } = (*self).into(); - let res_u128 = if index < BYTES_IN_U128 { - (low / one_shift_left_bytes_u128(index)) % POW_2_8 - } else { - (high / one_shift_left_bytes_u128(index - BYTES_IN_U128)) % POW_2_8 - }; - res_u128.try_into().unwrap() - } -} - -pub(crate) impl Bytes31IndexView of IndexView { - fn index(self: @bytes31, index: usize) -> u8 { - self.at(index) - } -} - -impl Bytes31BitSize of core::num::traits::BitSize { - fn bits() -> usize { - 248 - } -} - -pub(crate) impl Bytes31IntoFelt252 of Into { - fn into(self: bytes31) -> felt252 { - bytes31_to_felt252(self) - } -} - -pub(crate) impl Bytes31IntoU256 of Into { - fn into(self: bytes31) -> u256 { - let as_felt: felt252 = self.into(); - as_felt.into() - } -} - -pub(crate) impl Felt252TryIntoBytes31 of TryInto { - fn try_into(self: felt252) -> Option { - bytes31_try_from_felt252(self) - } -} - -impl Bytes31Serde = core::serde::into_felt252_based::SerdeImpl; - -pub(crate) impl U8IntoBytes31 of Into { - fn into(self: u8) -> bytes31 { - core::integer::upcast(self) - } -} -impl U16IntoBytes31 of Into { - fn into(self: u16) -> bytes31 { - core::integer::upcast(self) - } -} -impl U32IntoBytes31 of Into { - fn into(self: u32) -> bytes31 { - core::integer::upcast(self) - } -} -impl U64IntoBytes31 of Into { - fn into(self: u64) -> bytes31 { - core::integer::upcast(self) - } -} -pub(crate) impl U128IntoBytes31 of Into { - fn into(self: u128) -> bytes31 { - core::integer::upcast(self) - } -} - -// Splits a bytes31 into two bytes31s at the given index (LSB's index is 0). -// The bytes31s are represented using felt252s to improve performance. -// Note: this function assumes that: -// 1. `word` is validly convertible to a bytes31 which has no more than `len` bytes of data. -// 2. index <= len. -// 3. len <= BYTES_IN_BYTES31. -// If these assumptions are not met, it can corrupt the ByteArray. Thus, this should be a -// private function. We could add masking/assertions but it would be more expansive. -pub(crate) fn split_bytes31(word: felt252, len: usize, index: usize) -> (felt252, felt252) { - if index == 0 { - return (0, word); - } - if index == len { - return (word, 0); - } - - let u256 { low, high } = word.into(); - - if index == BYTES_IN_U128 { - return (low.into(), high.into()); - } - - if len <= BYTES_IN_U128 { - let (quotient, remainder) = u128_safe_divmod( - low, one_shift_left_bytes_u128(index).try_into().unwrap() - ); - return (remainder.into(), quotient.into()); - } - - // len > BYTES_IN_U128 - if index < BYTES_IN_U128 { - let (low_quotient, low_remainder) = u128_safe_divmod( - low, one_shift_left_bytes_u128(index).try_into().unwrap() - ); - let right = high.into() * one_shift_left_bytes_u128(BYTES_IN_U128 - index).into() - + low_quotient.into(); - return (low_remainder.into(), right); - } - - // len > BYTES_IN_U128 && index > BYTES_IN_U128 - let (high_quotient, high_remainder) = u128_safe_divmod( - high, one_shift_left_bytes_u128(index - BYTES_IN_U128).try_into().unwrap() - ); - let left = high_remainder.into() * POW_2_128 + low.into(); - return (left, high_quotient.into()); -} - - -// Returns 1 << (8 * `n_bytes`) as felt252, assuming that `n_bytes < BYTES_IN_BYTES31`. -// -// Note: if `n_bytes >= BYTES_IN_BYTES31`, the behavior is undefined. If one wants to assert that in -// the callsite, it's sufficient to assert that `n_bytes != BYTES_IN_BYTES31` because if -// `n_bytes > 31` then `n_bytes - 16 > 15` and `one_shift_left_bytes_u128` would panic. -pub(crate) fn one_shift_left_bytes_felt252(n_bytes: usize) -> felt252 { - if n_bytes < BYTES_IN_U128 { - one_shift_left_bytes_u128(n_bytes).into() - } else { - one_shift_left_bytes_u128(n_bytes - BYTES_IN_U128).into() * POW_2_128 - } -} - -// Returns 1 << (8 * `n_bytes`) as u128, where `n_bytes` must be < BYTES_IN_U128. -// -// Panics if `n_bytes >= BYTES_IN_U128`. -pub(crate) fn one_shift_left_bytes_u128(n_bytes: usize) -> u128 { - match n_bytes { - 0 => 0x1, - 1 => 0x100, - 2 => 0x10000, - 3 => 0x1000000, - 4 => 0x100000000, - 5 => 0x10000000000, - 6 => 0x1000000000000, - 7 => 0x100000000000000, - 8 => 0x10000000000000000, - 9 => 0x1000000000000000000, - 10 => 0x100000000000000000000, - 11 => 0x10000000000000000000000, - 12 => 0x1000000000000000000000000, - 13 => 0x100000000000000000000000000, - 14 => 0x10000000000000000000000000000, - 15 => 0x1000000000000000000000000000000, - _ => core::panic_with_felt252('n_bytes too big'), - } -} - -impl Bytes31PartialEq of PartialEq { - fn eq(lhs: @bytes31, rhs: @bytes31) -> bool { - let lhs_as_felt252: felt252 = (*lhs).into(); - let rhs_as_felt252: felt252 = (*rhs).into(); - lhs_as_felt252 == rhs_as_felt252 - } - fn ne(lhs: @bytes31, rhs: @bytes31) -> bool { - !(lhs == rhs) - } -} diff --git a/corelib/src/clone.cairo b/corelib/src/clone.cairo deleted file mode 100644 index 3a27f9910..000000000 --- a/corelib/src/clone.cairo +++ /dev/null @@ -1,10 +0,0 @@ -pub trait Clone { - #[must_use] - fn clone(self: @T) -> T; -} - -impl TCopyClone> of Clone { - fn clone(self: @T) -> T { - *self - } -} diff --git a/corelib/src/cmp.cairo b/corelib/src/cmp.cairo deleted file mode 100644 index 649933fec..000000000 --- a/corelib/src/cmp.cairo +++ /dev/null @@ -1,44 +0,0 @@ -/// Minimum of the two values. -/// # Arguments -/// * `a` - first comparable value -/// * `b` - Second comparable value -/// # Returns -/// * `result` - The smallest of the two values -#[must_use] -pub fn min, +Drop, +Copy>(a: T, b: T) -> T { - if a > b { - b - } else { - a - } -} - -/// Maximum of the two values. -/// # Arguments -/// * `a` - first comparable value -/// * `b` - Second comparable value -/// # Returns -/// * `result` - The greatest of the two values -#[must_use] -pub fn max, +Drop, +Copy>(a: T, b: T) -> T { - if a > b { - a - } else { - b - } -} - -/// Minimum and maximum of the two values. -/// # Arguments -/// * `a` - first comparable value -/// * `b` - Second comparable value -/// # Returns -/// * `result` - The two values sorted in ascending order -#[must_use] -pub fn minmax, +Drop, +Copy>(a: T, b: T) -> (T, T) { - if a > b { - (b, a) - } else { - (a, b) - } -} diff --git a/corelib/src/debug.cairo b/corelib/src/debug.cairo deleted file mode 100644 index f325f3477..000000000 --- a/corelib/src/debug.cairo +++ /dev/null @@ -1,132 +0,0 @@ -use core::array::ArrayTrait; -use core::traits::Into; -use core::option::Option; - -// Usage: -// -// use core::debug::PrintTrait; -// -// 1.print(); -// -// (1 == 2).print(); -// -// get_caller_address().print(); -// -// let mut arr = array![]; -// arr.append('1234567890123456789012345678901'); -// arr.append('Sca'); -// arr.append('SomeVeryLongMessage'); -// arr.print(); - -pub(crate) extern fn print(message: Array) nopanic; - -fn print_felt252(message: felt252) { - print(array![message]); -} - -pub(crate) trait PrintTrait { - fn print(self: T); -} - -pub(crate) impl Felt252PrintImpl of PrintTrait { - fn print(self: felt252) { - print_felt252(self); - } -} - -pub(crate) impl BoolPrintImpl of PrintTrait { - fn print(self: bool) { - if self { - 'true'.print(); - } else { - 'false'.print(); - } - } -} - -pub(crate) impl ContractAddressPrintImpl of PrintTrait { - fn print(self: starknet::ContractAddress) { - Into::<_, felt252>::into(self).print(); - } -} - -pub(crate) impl U8PrintImpl of PrintTrait { - fn print(self: u8) { - Into::<_, felt252>::into(self).print(); - } -} - -pub(crate) impl U16PrintImpl of PrintTrait { - fn print(self: u16) { - Into::<_, felt252>::into(self).print(); - } -} - -pub(crate) impl U32PrintImpl of PrintTrait { - fn print(self: u32) { - Into::<_, felt252>::into(self).print(); - } -} - -pub(crate) impl U64PrintImpl of PrintTrait { - fn print(self: u64) { - Into::<_, felt252>::into(self).print(); - } -} - -pub(crate) impl U128PrintImpl of PrintTrait { - fn print(self: u128) { - Into::<_, felt252>::into(self).print(); - } -} - -pub(crate) impl U256PrintImpl of PrintTrait { - fn print(self: u256) { - Into::::into(self.low).print(); - Into::::into(self.high).print(); - } -} - -pub(crate) impl I8PrintImpl of PrintTrait { - fn print(self: i8) { - Into::<_, felt252>::into(self).print(); - } -} - -pub(crate) impl I16PrintImpl of PrintTrait { - fn print(self: i16) { - Into::<_, felt252>::into(self).print(); - } -} - -pub(crate) impl I32PrintImpl of PrintTrait { - fn print(self: i32) { - Into::<_, felt252>::into(self).print(); - } -} - -pub(crate) impl I64PrintImpl of PrintTrait { - fn print(self: i64) { - Into::<_, felt252>::into(self).print(); - } -} - -pub(crate) impl I128PrintImpl of PrintTrait { - fn print(self: i128) { - Into::<_, felt252>::into(self).print(); - } -} - -pub(crate) impl ArrayGenericPrintImpl of PrintTrait> { - fn print(mut self: Array) { - print(self); - } -} - -/// Prints a byte array as a string. -pub fn print_byte_array_as_string(self: @ByteArray) { - let mut serialized = array![core::byte_array::BYTE_ARRAY_MAGIC]; - self.serialize(ref serialized); - print(serialized) -} - diff --git a/corelib/src/dict.cairo b/corelib/src/dict.cairo deleted file mode 100644 index b6de59fec..000000000 --- a/corelib/src/dict.cairo +++ /dev/null @@ -1,105 +0,0 @@ -use core::traits::{Index, Default, Felt252DictValue}; - -pub extern type Felt252Dict; -pub extern type SquashedFelt252Dict; -pub extern type Felt252DictEntry; -impl SquashedFelt252DictDrop> of Drop>; - -pub(crate) extern fn felt252_dict_new() -> Felt252Dict implicits(SegmentArena) nopanic; - -extern fn felt252_dict_entry_get( - dict: Felt252Dict, key: felt252 -) -> (Felt252DictEntry, T) nopanic; - -extern fn felt252_dict_entry_finalize( - dict_entry: Felt252DictEntry, new_value: T -) -> Felt252Dict nopanic; - -/// Squashes the dictionary and returns SquashedFelt252Dict. -/// -/// NOTE: Never use this libfunc directly. Use Felt252DictTrait::squash() instead. Using this -/// libfunc directly will result in multiple unnecessary copies of the libfunc in the compiled CASM -/// code. -pub(crate) extern fn felt252_dict_squash( - dict: Felt252Dict -) -> SquashedFelt252Dict implicits(RangeCheck, GasBuiltin, SegmentArena) nopanic; - -pub trait Felt252DictTrait { - /// Inserts the given value for the given key. - /// - /// Requires the `Destruct` trait, as the previous value is dropped. - fn insert<+Destruct>(ref self: Felt252Dict, key: felt252, value: T); - /// Returns a copy of the value at the given key. - /// - /// Requires the `Copy` trait. - fn get<+Copy>(ref self: Felt252Dict, key: felt252) -> T; - fn squash(self: Felt252Dict) -> SquashedFelt252Dict nopanic; - #[must_use] - fn entry(self: Felt252Dict, key: felt252) -> (Felt252DictEntry, T) nopanic; -} -impl Felt252DictImpl> of Felt252DictTrait { - #[inline] - fn insert<+Destruct>(ref self: Felt252Dict, key: felt252, value: T) { - let (entry, _prev_value) = felt252_dict_entry_get(self, key); - self = felt252_dict_entry_finalize(entry, value); - } - - #[inline] - fn get<+Copy>(ref self: Felt252Dict, key: felt252) -> T { - let (entry, prev_value) = felt252_dict_entry_get(self, key); - let return_value = prev_value; - self = felt252_dict_entry_finalize(entry, prev_value); - return_value - } - - #[inline(never)] - fn squash(self: Felt252Dict) -> SquashedFelt252Dict nopanic { - felt252_dict_squash(self) - } - - #[inline(always)] - fn entry(self: Felt252Dict, key: felt252) -> (Felt252DictEntry, T) nopanic { - felt252_dict_entry_get(self, key) - } -} - -pub trait Felt252DictEntryTrait { - fn finalize(self: Felt252DictEntry, new_value: T) -> Felt252Dict; -} - -impl Felt252DictEntryImpl> of Felt252DictEntryTrait { - #[inline(always)] - fn finalize(self: Felt252DictEntry, new_value: T) -> Felt252Dict { - felt252_dict_entry_finalize(self, new_value) - } -} - -impl Felt252DictDefault of Default> { - #[inline(always)] - fn default() -> Felt252Dict { - felt252_dict_new() - } -} - -impl Felt252DictDestruct, +Felt252DictValue> of Destruct> { - #[inline(always)] - fn destruct(self: Felt252Dict) nopanic { - self.squash(); - } -} - -impl Felt252DictEntryDestruct, +Felt252DictValue> of Destruct> { - #[inline(always)] - fn destruct(self: Felt252DictEntry::) nopanic { - felt252_dict_entry_finalize(self, Felt252DictValue::zero_default()); - } -} - -impl Felt252DictIndex< - T, +Felt252DictTrait, +Copy, +Destruct> -> of Index, felt252, T> { - #[inline(always)] - fn index(ref self: Felt252Dict, index: felt252) -> T { - self.get(index) - } -} diff --git a/corelib/src/ec.cairo b/corelib/src/ec.cairo deleted file mode 100644 index 7a64fc31a..000000000 --- a/corelib/src/ec.cairo +++ /dev/null @@ -1,215 +0,0 @@ -//! This module contains functions and constructs related to elliptic curve operations on the Stark -//! curve. - -use core::array::ArrayTrait; -use core::traits::{Into, TryInto}; -use core::zeroable::IsZeroResult; - -pub mod stark_curve { - /// The STARK Curve is defined by the equation `y^2 = x^3 + ALPHA*x + BETA`. - pub const ALPHA: felt252 = 1; - /// The STARK Curve is defined by the equation `y^2 = x^3 + ALPHA*x + BETA`. - pub const BETA: felt252 = 0x6f21413efbe40de150e596d72f7a8c5609ad26c15c915c1f4cdfcb99cee9e89; - /// The order (number of points) of the STARK Curve. - pub const ORDER: felt252 = 0x800000000000010ffffffffffffffffb781126dcae7b2321e66a241adc64d2f; - /// The x coordinate of the generator point used in the ECDSA signature. - pub const GEN_X: felt252 = 0x1ef15c18599971b7beced415a40f0c7deacfd9b0d1819e03d723d8bc943cfca; - /// The y coordinate of the generator point used in the ECDSA signature. - pub const GEN_Y: felt252 = 0x5668060aa49730b7be4801df46ec62de53ecd11abe43a32873000c36e8dc1f; -} - -pub extern type EcOp; -#[derive(Copy, Drop)] -pub extern type EcPoint; -pub type NonZeroEcPoint = NonZero; - -/// Returns the zero point of the curve ("the point at infinity"). -extern fn ec_point_zero() -> EcPoint nopanic; -/// Constructs a non-zero point from its (x, y) coordinates. -/// Returns `None` if the point (x, y) is not on the curve. -extern fn ec_point_try_new_nz(x: felt252, y: felt252) -> Option nopanic; -/// Constructs a non-zero point from its x coordinate. -/// Returns `None` if no point of form (x, _) is on the curve. -extern fn ec_point_from_x_nz(x: felt252) -> Option implicits(RangeCheck) nopanic; -/// Unwraps a non-zero point into its (x, y) coordinates. -pub extern fn ec_point_unwrap(p: NonZeroEcPoint) -> (felt252, felt252) nopanic; -/// Computes the negation of an elliptic curve point (-p). -extern fn ec_neg(p: EcPoint) -> EcPoint nopanic; -/// Checks whether the given `EcPoint` is the zero point. -extern fn ec_point_is_zero(p: EcPoint) -> IsZeroResult nopanic; - -/// Converts `EcPoint` to `NonZeroEcPoint`. -impl EcPointTryIntoNonZero of TryInto { - #[inline(always)] - fn try_into(self: EcPoint) -> Option { - match ec_point_is_zero(self) { - IsZeroResult::Zero => Option::None, - IsZeroResult::NonZero(p_nz) => Option::Some(p_nz), - } - } -} - -// EC state. -#[derive(Drop)] -pub extern type EcState; - -mod internal { - impl EcStateCopy of Copy; - pub impl EcStateClone of Clone { - #[inline(always)] - fn clone(self: @super::EcState) -> super::EcState { - *self - } - } -} -impl EcStateClone = internal::EcStateClone; - -/// Initializes an EC computation with the zero point. -extern fn ec_state_init() -> EcState nopanic; - -/// Adds a point to the computation. -extern fn ec_state_add(ref s: EcState, p: NonZeroEcPoint) nopanic; -/// Adds the product p * scalar to the state. -extern fn ec_state_add_mul( - ref s: EcState, scalar: felt252, p: NonZeroEcPoint -) implicits(EcOp) nopanic; -/// Finalizes the EC computation and returns the result (returns `None` if the result is the -/// zero point). -extern fn ec_state_try_finalize_nz(s: EcState) -> Option nopanic; - -#[generate_trait] -pub impl EcStateImpl of EcStateTrait { - /// Initializes an EC computation with the zero point. - #[must_use] - fn init() -> EcState nopanic { - ec_state_init() - } - /// Adds a point to the computation. - #[inline(always)] - fn add(ref self: EcState, p: NonZeroEcPoint) nopanic { - ec_state_add(ref self, :p); - } - /// Subs a point to the computation. - #[inline(always)] - fn sub(ref self: EcState, p: NonZeroEcPoint) { - // TODO(orizi): Have a `ec_neg` for NonZeroEcPoint as well, or a `ec_state_sub`. - let p: EcPoint = p.into(); - let p_neg = ec_neg(p); - let p_neg_nz = p_neg.try_into().unwrap(); - ec_state_add(ref self, p_neg_nz); - } - /// Adds the product p * scalar to the state. - #[inline(always)] - fn add_mul(ref self: EcState, scalar: felt252, p: NonZeroEcPoint) nopanic { - ec_state_add_mul(ref self, :scalar, :p); - } - /// Finalizes the EC computation and returns the result (returns `None` if the result is the - /// zero point). - #[inline(always)] - fn finalize_nz(self: EcState) -> Option nopanic { - ec_state_try_finalize_nz(self) - } - /// Finalizes the EC computation and returns the result. - #[inline(always)] - fn finalize(self: EcState) -> EcPoint { - match self.finalize_nz() { - Option::Some(p_nz) => p_nz.into(), - Option::None => ec_point_zero(), - } - } -} - -#[generate_trait] -pub impl EcPointImpl of EcPointTrait { - /// Creates a new EC point from its (x, y) coordinates. - #[inline(always)] - fn new(x: felt252, y: felt252) -> Option { - Option::Some(EcPointTrait::new_nz(:x, :y)?.into()) - } - /// Creates a new NonZero EC point from its (x, y) coordinates. - #[inline(always)] - fn new_nz(x: felt252, y: felt252) -> Option { - ec_point_try_new_nz(:x, :y) - } - /// Creates a new EC point from its x coordinate. - #[inline(always)] - fn new_from_x(x: felt252) -> Option { - Option::Some(EcPointTrait::new_nz_from_x(:x)?.into()) - } - /// Creates a new NonZero EC point from its x coordinate. - #[inline(always)] - fn new_nz_from_x(x: felt252) -> Option { - ec_point_from_x_nz(:x) - } - /// Returns the coordinates of the EC point. - #[inline(always)] - fn coordinates(self: NonZeroEcPoint) -> (felt252, felt252) { - ec_point_unwrap(self) - } - /// Computes the product of an EC point `p` by the given scalar `scalar`. - fn mul(self: EcPoint, scalar: felt252) -> EcPoint { - match self.try_into() { - Option::Some(self_nz) => { - let mut state = EcStateTrait::init(); - state.add_mul(scalar, self_nz); - state.finalize() - }, - Option::None => self, - } - } -} - -impl EcPointNeg of Neg { - fn neg(a: EcPoint) -> EcPoint { - ec_neg(a) - } -} - -impl EcPointAdd of Add { - /// Computes the sum of two points on the curve. - // TODO(lior): Implement using a libfunc to make it more efficient. - fn add(lhs: EcPoint, rhs: EcPoint) -> EcPoint { - let lhs_nz = match lhs.try_into() { - Option::Some(pt) => pt, - Option::None => { return rhs; }, - }; - let rhs_nz = match rhs.try_into() { - Option::Some(pt) => pt, - Option::None => { return lhs; }, - }; - let mut state = ec_state_init(); - state.add(lhs_nz); - state.add(rhs_nz); - state.finalize() - } -} - -impl EcPointAddEq of AddEq { - #[inline(always)] - fn add_eq(ref self: EcPoint, other: EcPoint) { - self = Add::add(self, other); - } -} - -impl EcPointSub of Sub { - /// Computes the difference between two points on the curve. - fn sub(lhs: EcPoint, rhs: EcPoint) -> EcPoint { - let nz_point: Option> = rhs.try_into(); - match nz_point { - Option::Some(_) => {}, - Option::None => { - // lhs - 0 = lhs. - return lhs; - }, - }; - // lhs - rhs = lhs + (-rhs). - lhs + (-rhs) - } -} - -impl EcPointSubEq of SubEq { - #[inline(always)] - fn sub_eq(ref self: EcPoint, other: EcPoint) { - self = Sub::sub(self, other); - } -} diff --git a/corelib/src/ecdsa.cairo b/corelib/src/ecdsa.cairo deleted file mode 100644 index 032acc9f9..000000000 --- a/corelib/src/ecdsa.cairo +++ /dev/null @@ -1,162 +0,0 @@ -use core::{ec, ec::{EcPoint, EcPointTrait, EcStateTrait}}; -use core::option::OptionTrait; -use core::math; -use core::traits::{Into, TryInto}; -use core::zeroable::IsZeroResult; - -// Checks if (`signature_r`, `signature_s`) is a valid ECDSA signature for the given `public_key` -// on the given `message`. -// -// Note: the verification algorithm implemented by this function slightly deviates from the -// standard ECDSA. -// While this does not allow to create valid signatures if one does not possess the private key, -// it means that the signature algorithm used should be modified accordingly. -// Namely, it should check that `r, s < stark_curve::ORDER`. -// -// Arguments: -// * `message_hash` - the signed message. -// * `public_key` - the public key corresponding to the key with which the message was signed. -// * `signature_r` - the `r` component of the ECDSA signature. -// * `signature_s` - the `s` component of the ECDSA signature. -// -// Returns: -// `true` if the signature is valid and `false` otherwise. -// TODO(lior): Make this function nopanic once possible. -pub fn check_ecdsa_signature( - message_hash: felt252, public_key: felt252, signature_r: felt252, signature_s: felt252 -) -> bool { - // TODO(orizi): Change to || once it does not prevent `a == 0` comparison optimization. - // Check that s != 0 (mod stark_curve::ORDER). - if signature_s == 0 { - return false; - } - if signature_s == ec::stark_curve::ORDER { - return false; - } - if signature_r == ec::stark_curve::ORDER { - return false; - } - - // Check that the public key is the x coordinate of a point on the curve and get such a point. - let public_key_point = match EcPointTrait::new_nz_from_x(public_key) { - Option::Some(point) => point, - Option::None => { return false; }, - }; - - // Check that `r` is the x coordinate of a point on the curve and get such a point. - // Note that this ensures that `r != 0`. - let signature_r_point = match EcPointTrait::new_nz_from_x(signature_r) { - Option::Some(point) => point, - Option::None => { return false; }, - }; - - // Retrieve the generator point. - let gen_point = match EcPointTrait::new_nz(ec::stark_curve::GEN_X, ec::stark_curve::GEN_Y) { - Option::Some(point) => point, - Option::None => { return false; }, - }; - - // Initialize an EC state. - let init_ec = EcStateTrait::init(); - - // To verify ECDSA, obtain: - // zG = z * G, where z is the message and G is a generator of the EC. - // rQ = r * Q, where Q.x = public_key. - // sR = s * R, where R.x = r. - // and check that: - // zG +/- rQ = +/- sR, or more efficiently that: - // (zG +/- rQ).x = sR.x. - - // Calculate `sR.x`. - let mut sR_state = init_ec.clone(); - sR_state.add_mul(signature_s, signature_r_point); - let sR_x = match sR_state.finalize_nz() { - Option::Some(pt) => { - let (x, _) = ec::ec_point_unwrap(pt); - x - }, - Option::None => { return false; }, - }; - - // Calculate a state with `z * G`. - let mut zG_state = init_ec.clone(); - zG_state.add_mul(message_hash, gen_point); - - // Calculate the point `r * Q`. - let mut rQ_state = init_ec; - rQ_state.add_mul(signature_r, public_key_point); - let rQ = match rQ_state.finalize_nz() { - Option::Some(pt) => pt, - // The zero case is not actually possible, as `signature_r` isn't 0. - Option::None => { return false; }, - }; - - // Check the `(zG + rQ).x = sR.x` case. - let mut zG_plus_eQ_state = zG_state.clone(); - zG_plus_eQ_state.add(rQ); - match zG_plus_eQ_state.finalize_nz() { - Option::Some(pt) => { - let (x, _) = ec::ec_point_unwrap(pt); - if (x == sR_x) { - return true; - } - }, - Option::None => {}, - }; - - // Check the `(zG - rQ).x = sR.x` case. - let mut zG_minus_eQ_state = zG_state; - zG_minus_eQ_state.sub(rQ); - match zG_minus_eQ_state.finalize_nz() { - Option::Some(pt) => { - let (x, _) = ec::ec_point_unwrap(pt); - if (x == sR_x) { - return true; - } - }, - Option::None => {}, - }; - - return false; -} - -/// Receives a signature and the signed message hash. -/// Returns the public key associated with the signer. -pub fn recover_public_key( - message_hash: felt252, signature_r: felt252, signature_s: felt252, y_parity: bool -) -> Option { - let mut signature_r_point = EcPointTrait::new_from_x(signature_r)?; - let (_, y) = signature_r_point.try_into()?.coordinates(); - let y: u256 = y.into(); - // If the actual the parity of the actual y is different than requested, flip the parity. - if (y.low & 1 == 1) != y_parity { - signature_r_point = -signature_r_point; - } - - // Retrieve the generator point. - let gen_point = EcPointTrait::new(ec::stark_curve::GEN_X, ec::stark_curve::GEN_Y)?; - - // a Valid signature should satisfy: - // zG + rQ = sR. - // Where: - // zG = z * G, z is the message and G is a generator of the EC. - // rQ = r * Q, Q.x = public_key. - // sR = s * R, where R.x = r and R.y is determined by y_parity. - // - // Hence: - // rQ = sR - zG. - // Q = (s/r)R - (z/r)G - // and we can recover the public key using: - // Q.x = ((s/r)R - (z/r)G).x. - let r_nz: u256 = signature_r.into(); - let r_nz = r_nz.try_into()?; - let ord_nz: u256 = ec::stark_curve::ORDER.into(); - let ord_nz = ord_nz.try_into()?; - let r_inv = math::u256_inv_mod(r_nz, ord_nz)?.into(); - let s_div_r: felt252 = math::u256_mul_mod_n(signature_s.into(), r_inv, ord_nz).try_into()?; - let z_div_r: felt252 = math::u256_mul_mod_n(message_hash.into(), r_inv, ord_nz).try_into()?; - let s_div_rR: EcPoint = signature_r_point.mul(s_div_r); - let z_div_rG: EcPoint = gen_point.mul(z_div_r); - let (x, _) = (s_div_rR - z_div_rG).try_into()?.coordinates(); - Option::Some(x) -} diff --git a/corelib/src/felt_252.cairo b/corelib/src/felt_252.cairo deleted file mode 100644 index f1f9f1e0d..000000000 --- a/corelib/src/felt_252.cairo +++ /dev/null @@ -1,31 +0,0 @@ -pub(crate) impl Felt252Zero of core::num::traits::Zero { - fn zero() -> felt252 { - 0 - } - - #[inline(always)] - fn is_zero(self: @felt252) -> bool { - *self == Felt252Zero::zero() - } - - #[inline(always)] - fn is_non_zero(self: @felt252) -> bool { - !self.is_zero() - } -} - -pub(crate) impl Felt252One of core::num::traits::One { - fn one() -> felt252 { - 1 - } - - #[inline(always)] - fn is_one(self: @felt252) -> bool { - *self == Felt252One::one() - } - - #[inline(always)] - fn is_non_one(self: @felt252) -> bool { - !self.is_one() - } -} diff --git a/corelib/src/fmt.cairo b/corelib/src/fmt.cairo deleted file mode 100644 index 4260f34f5..000000000 --- a/corelib/src/fmt.cairo +++ /dev/null @@ -1,204 +0,0 @@ -#[derive(Drop)] -pub struct Error {} - -/// Configuration for formatting. -#[derive(Default, Drop)] -pub struct Formatter { - /// The pending result of formatting. - pub buffer: ByteArray, -} - -/// A trait for standard formatting, using the empty format ("{}"). -pub trait Display { - fn fmt(self: @T, ref f: Formatter) -> Result<(), Error>; -} - -impl DisplayByteArray of Display { - fn fmt(self: @ByteArray, ref f: Formatter) -> Result<(), Error> { - f.buffer.append(self); - Result::Ok(()) - } -} - -impl DisplayInteger< - T, +to_byte_array::AppendFormattedToByteArray, +Into, +TryInto> -> of Display { - fn fmt(self: @T, ref f: Formatter) -> Result<(), Error> { - // TODO(yuval): determine base according to Formatter parameters. - let base: T = 10_u8.into(); - self.append_formatted_to_byte_array(ref f.buffer, base.try_into().unwrap()); - Result::Ok(()) - } -} - -impl DisplayNonZero, +Copy, +Drop> of Display> { - fn fmt(self: @NonZero, ref f: Formatter) -> Result<(), Error> { - let value: T = (*self).into(); - write!(f, "{value}") - } -} - -impl DisplayBool of Display { - fn fmt(self: @bool, ref f: Formatter) -> Result<(), Error> { - if *self { - write!(f, "true") - } else { - write!(f, "false") - } - } -} - -impl DisplaySnapshot> of Display<@T> { - fn fmt(self: @@T, ref f: Formatter) -> Result<(), Error> { - Display::fmt(*self, ref f) - } -} - -/// A trait for debug formatting, using the empty format ("{:?}"). -pub trait Debug { - fn fmt(self: @T, ref f: Formatter) -> Result<(), Error>; -} - -impl DebugByteArray of Debug { - fn fmt(self: @ByteArray, ref f: Formatter) -> Result<(), Error> { - write!(f, "\"")?; - Display::fmt(self, ref f)?; - write!(f, "\"") - } -} - -impl DebugInteger< - T, +to_byte_array::AppendFormattedToByteArray, +Into, +TryInto> -> of Debug { - fn fmt(self: @T, ref f: Formatter) -> Result<(), Error> { - Display::fmt(self, ref f) - } -} - -impl DebugNonZero, +Copy, +Drop> of Debug> { - fn fmt(self: @NonZero, ref f: Formatter) -> Result<(), Error> { - let value: T = (*self).into(); - write!(f, "{value:?}") - } -} - -impl DebugBool of Debug { - fn fmt(self: @bool, ref f: Formatter) -> Result<(), Error> { - Display::fmt(self, ref f) - } -} - -impl DebugSnapshot> of Debug<@T> { - fn fmt(self: @@T, ref f: Formatter) -> Result<(), Error> { - write!(f, "@")?; - Debug::fmt(*self, ref f) - } -} - -impl DebugTuple0 of Debug<()> { - fn fmt(self: @(), ref f: Formatter) -> Result<(), Error> { - write!(f, "()") - } -} - -impl DebugTuple1> of Debug<(E0,)> { - fn fmt(self: @(E0,), ref f: Formatter) -> Result<(), Error> { - let (e0,) = self; - write!(f, "(")?; - E0Debug::fmt(e0, ref f)?; - write!(f, ",)") - } -} - -impl DebugTuple2, impl E1Debug: Debug> of Debug<(E0, E1)> { - fn fmt(self: @(E0, E1), ref f: Formatter) -> Result<(), Error> { - let (e0, e1) = self; - write!(f, "(")?; - E0Debug::fmt(e0, ref f)?; - write!(f, ", ")?; - E1Debug::fmt(e1, ref f)?; - write!(f, ")") - } -} - -impl DebugTuple3< - E0, E1, E2, impl E0Debug: Debug, impl E1Debug: Debug, impl E2Debug: Debug -> of Debug<(E0, E1, E2)> { - fn fmt(self: @(E0, E1, E2), ref f: Formatter) -> Result<(), Error> { - let (e0, e1, e2) = self; - write!(f, "(")?; - E0Debug::fmt(e0, ref f)?; - write!(f, ", ")?; - E1Debug::fmt(e1, ref f)?; - write!(f, ", ")?; - E2Debug::fmt(e2, ref f)?; - write!(f, ")") - } -} - -impl DebugTuple4< - E0, - E1, - E2, - E3, - impl E0Debug: Debug, - impl E1Debug: Debug, - impl E2Debug: Debug, - impl E3Debug: Debug -> of Debug<(E0, E1, E2, E3)> { - fn fmt(self: @(E0, E1, E2, E3), ref f: Formatter) -> Result<(), Error> { - let (e0, e1, e2, e3) = self; - write!(f, "(")?; - E0Debug::fmt(e0, ref f)?; - write!(f, ", ")?; - E1Debug::fmt(e1, ref f)?; - write!(f, ", ")?; - E2Debug::fmt(e2, ref f)?; - write!(f, ", ")?; - E3Debug::fmt(e3, ref f)?; - write!(f, ")") - } -} - -impl ArrayTDebug> of Debug> { - fn fmt(self: @Array, ref f: Formatter) -> Result<(), Error> { - Debug::fmt(@self.span(), ref f) - } -} - -impl SpanTDebug> of Debug> { - fn fmt(self: @Span, ref f: Formatter) -> Result<(), Error> { - let mut self = *self; - write!(f, "[")?; - loop { - match self.pop_front() { - Option::Some(value) => { - if Debug::fmt(value, ref f).is_err() { - break Result::Err(Error {}); - }; - if self.is_empty() { - break Result::Ok(()); - } - if write!(f, ", ").is_err() { - break Result::Err(Error {}); - }; - }, - Option::None => { break Result::Ok(()); } - }; - }?; - write!(f, "]") - } -} - -/// Impls for `Debug` for types that can be converted into `felt252` using the `Into` trait. -/// Usage example: -/// ```ignore -/// impl MyTypeDebug = core::fmt::into_felt252_based::DebugImpl;` -/// ``` -pub mod into_felt252_based { - pub impl DebugImpl, +Copy> of core::fmt::Debug { - fn fmt(self: @T, ref f: core::fmt::Formatter) -> Result<(), core::fmt::Error> { - core::fmt::DebugInteger::::fmt(@(*self).into(), ref f) - } - } -} diff --git a/corelib/src/gas.cairo b/corelib/src/gas.cairo deleted file mode 100644 index 6ef2c70af..000000000 --- a/corelib/src/gas.cairo +++ /dev/null @@ -1,9 +0,0 @@ -#[derive(Copy, Drop)] -pub extern type BuiltinCosts; -pub extern type GasBuiltin; - -pub extern fn withdraw_gas() -> Option<()> implicits(RangeCheck, GasBuiltin) nopanic; -pub extern fn withdraw_gas_all( - costs: BuiltinCosts -) -> Option<()> implicits(RangeCheck, GasBuiltin) nopanic; -pub extern fn get_builtin_costs() -> BuiltinCosts nopanic; diff --git a/corelib/src/hash.cairo b/corelib/src/hash.cairo deleted file mode 100644 index 5556f0244..000000000 --- a/corelib/src/hash.cairo +++ /dev/null @@ -1,150 +0,0 @@ -use core::traits::Into; - -/// A trait for hash state accumulators. -pub trait HashStateTrait { - #[must_use] - fn update(self: S, value: felt252) -> S; - #[must_use] - fn finalize(self: S) -> felt252; -} - -/// A trait for values that can be hashed. -pub trait Hash> { - /// Updates the hash state with the given value. - #[must_use] - fn update_state(state: S, value: T) -> S; -} - -/// Trait for hashing values. -/// Used for backwards compatibility. -/// NOTE: Implement `Hash` instead of this trait if possible. -pub trait LegacyHash { - #[must_use] - fn hash(state: felt252, value: T) -> felt252; -} - -/// Implementation of `LegacyHash` for types that have `Hash` for backwards compatibility. -impl LegacyHashForHash> of LegacyHash { - #[inline(always)] - fn hash(state: felt252, value: T) -> felt252 { - core::pedersen::HashState { state }.update_with(value).state - } -} - -/// Extension trait for hash state accumulators. -pub trait HashStateExTrait { - /// Updates the hash state with the given value. - #[must_use] - fn update_with(self: S, value: T) -> S; -} - -impl HashStateEx, T, +Hash> of HashStateExTrait { - #[inline(always)] - fn update_with(self: S, value: T) -> S { - Hash::update_state(self, value) - } -} - -impl HashFelt252> of Hash { - #[inline(always)] - fn update_state(state: S, value: felt252) -> S { - state.update(value) - } -} - -/// Impl for `Hash` for types that can be converted into `felt252` using the `Into` trait. -/// Usage example: -/// ```ignore -/// impl MyTypeHash, +Drop> = -/// core::hash::into_felt252_based::HashImpl;` -/// ``` -pub mod into_felt252_based { - pub impl HashImpl< - T, S, +Into, +super::HashStateTrait, +Drop - > of super::Hash { - #[inline(always)] - fn update_state(state: S, value: T) -> S { - state.update(value.into()) - } - } -} - -impl HashBool, +Drop> = into_felt252_based::HashImpl; -impl HashU8, +Drop> = into_felt252_based::HashImpl; -impl HashU16, +Drop> = into_felt252_based::HashImpl; -impl HashU32, +Drop> = into_felt252_based::HashImpl; -impl HashU64, +Drop> = into_felt252_based::HashImpl; -impl HashU128, +Drop> = into_felt252_based::HashImpl; -impl HashI8, +Drop> = into_felt252_based::HashImpl; -impl HashI16, +Drop> = into_felt252_based::HashImpl; -impl HashI32, +Drop> = into_felt252_based::HashImpl; -impl HashI64, +Drop> = into_felt252_based::HashImpl; -impl HashI128, +Drop> = into_felt252_based::HashImpl; - -impl TupleSize0Hash> of Hash<(), S> { - #[inline(always)] - fn update_state(state: S, value: ()) -> S { - state - } -} - -impl TupleSize1Hash, +HashStateTrait> of Hash<(E0,), S> { - #[inline(always)] - fn update_state(state: S, value: (E0,)) -> S { - let (e0,) = value; - state.update_with(e0) - } -} - -impl TupleSize2Hash< - E0, E1, S, +HashStateTrait, +Hash, +Hash, +Drop, +Drop, -> of Hash<(E0, E1), S> { - #[inline(always)] - fn update_state(state: S, value: (E0, E1,)) -> S { - let (e0, e1) = value; - state.update_with(e0).update_with(e1) - } -} - -impl TupleSize3Hash< - E0, - E1, - E2, - S, - +HashStateTrait, - +Hash, - +Hash, - +Hash, - +Drop, - +Drop, - +Drop, -> of Hash<(E0, E1, E2), S> { - #[inline(always)] - fn update_state(state: S, value: (E0, E1, E2)) -> S { - let (e0, e1, e2) = value; - state.update_with(e0).update_with(e1).update_with(e2) - } -} - -impl TupleSize4Hash< - E0, - E1, - E2, - E3, - S, - +HashStateTrait, - +Hash, - +Hash, - +Hash, - +Hash, - +Drop, - +Drop, - +Drop, - +Drop, -> of Hash<(E0, E1, E2, E3), S> { - #[inline(always)] - fn update_state(state: S, value: (E0, E1, E2, E3)) -> S { - let (e0, e1, e2, e3) = value; - state.update_with(e0).update_with(e1).update_with(e2).update_with(e3) - } -} diff --git a/corelib/src/integer.cairo b/corelib/src/integer.cairo deleted file mode 100644 index bd395bea9..000000000 --- a/corelib/src/integer.cairo +++ /dev/null @@ -1,3046 +0,0 @@ -use core::option::OptionTrait; -use core::result::ResultTrait; -use core::traits::{Into, TryInto, Default, Felt252DictValue}; -use core::zeroable::{IsZeroResult, NonZeroIntoImpl, Zeroable}; -use core::array::ArrayTrait; -use core::array::SpanTrait; - -// TODO(spapini): Add method for const creation from Integer. -pub trait NumericLiteral; -impl NumericLiteralfelt252 of NumericLiteral; - -impl NumericLiteralNonZero> of NumericLiteral>; - -#[derive(Copy, Drop)] -pub extern type u128; -impl NumericLiteralu128 of NumericLiteral; - -impl U128Serde = core::serde::into_felt252_based::SerdeImpl; - -enum U128sFromFelt252Result { - Narrow: u128, - Wide: (u128, u128), -} -extern fn u128s_from_felt252(a: felt252) -> U128sFromFelt252Result implicits(RangeCheck) nopanic; - -#[panic_with('u128_from Overflow', u128_from_felt252)] -fn u128_try_from_felt252(a: felt252) -> Option implicits(RangeCheck) nopanic { - match u128s_from_felt252(a) { - U128sFromFelt252Result::Narrow(x) => Option::Some(x), - U128sFromFelt252Result::Wide(_x) => Option::None, - } -} - -pub(crate) extern fn u128_to_felt252(a: u128) -> felt252 nopanic; - -pub extern fn u128_overflowing_add( - lhs: u128, rhs: u128 -) -> Result implicits(RangeCheck) nopanic; -pub extern fn u128_overflowing_sub( - lhs: u128, rhs: u128 -) -> Result implicits(RangeCheck) nopanic; - -pub fn u128_wrapping_add(lhs: u128, rhs: u128) -> u128 implicits(RangeCheck) nopanic { - match u128_overflowing_add(lhs, rhs) { - Result::Ok(x) => x, - Result::Err(x) => x, - } -} - -pub fn u128_wrapping_sub(a: u128, b: u128) -> u128 implicits(RangeCheck) nopanic { - match u128_overflowing_sub(a, b) { - Result::Ok(x) => x, - Result::Err(x) => x, - } -} - -/// A type that contains 4 u128s (a, b, c, d) and guarantees that `a * b = 2**128 * c + d`. -/// -/// The guarantee is verified by `u128_mul_guarantee_verify`, which is the only way to destruct this -/// type. This way, one can trust that the guarantee holds although it has not yet been verified. -pub extern type U128MulGuarantee; - -/// Multiplies two u128s and returns a `U128MulGuarantee` for the result of `a * b`. -extern fn u128_guarantee_mul(a: u128, b: u128) -> (u128, u128, U128MulGuarantee) nopanic; - -/// Verifies the guarantee and returns the result of `a * b`. -extern fn u128_mul_guarantee_verify(guarantee: U128MulGuarantee) implicits(RangeCheck) nopanic; - -/// Multiplies two u128s and returns `(high, low)` - the 128-bit parts of the result. -#[inline(always)] -pub fn u128_wide_mul(a: u128, b: u128) -> (u128, u128) nopanic { - let (high, low, _) = u128_guarantee_mul(a, b); - (high, low) -} - -impl U128MulGuaranteeDestruct of Destruct { - fn destruct(self: U128MulGuarantee) nopanic { - u128_mul_guarantee_verify(self); - } -} - -pub extern fn u128_sqrt(value: u128) -> u64 implicits(RangeCheck) nopanic; - -pub fn u128_overflowing_mul(lhs: u128, rhs: u128) -> (u128, bool) implicits(RangeCheck) nopanic { - let (top_word, bottom_word) = u128_wide_mul(lhs, rhs); - match u128_to_felt252(top_word) { - 0 => (bottom_word, false), - _ => (bottom_word, true), - } -} - - -fn u128_checked_add(lhs: u128, rhs: u128) -> Option implicits(RangeCheck) nopanic { - match u128_overflowing_add(lhs, rhs) { - Result::Ok(r) => Option::Some(r), - Result::Err(_r) => Option::None, - } -} - -impl U128Add of Add { - fn add(lhs: u128, rhs: u128) -> u128 { - u128_overflowing_add(lhs, rhs).expect('u128_add Overflow') - } -} -impl U128AddEq of AddEq { - #[inline(always)] - fn add_eq(ref self: u128, other: u128) { - self = Add::add(self, other); - } -} - -#[panic_with('u128_sub Overflow', u128_sub)] -fn u128_checked_sub(lhs: u128, rhs: u128) -> Option implicits(RangeCheck) nopanic { - match u128_overflowing_sub(lhs, rhs) { - Result::Ok(r) => Option::Some(r), - Result::Err(_r) => Option::None, - } -} - -impl U128Sub of Sub { - fn sub(lhs: u128, rhs: u128) -> u128 { - u128_overflowing_sub(lhs, rhs).expect('u128_sub Overflow') - } -} -impl U128SubEq of SubEq { - #[inline(always)] - fn sub_eq(ref self: u128, other: u128) { - self = Sub::sub(self, other); - } -} - -fn u128_checked_mul(lhs: u128, rhs: u128) -> Option implicits(RangeCheck) nopanic { - let (top_word, bottom_word) = u128_wide_mul(lhs, rhs); - match u128_to_felt252(top_word) { - 0 => Option::Some(bottom_word), - _ => Option::None, - } -} - -impl U128Mul of Mul { - fn mul(lhs: u128, rhs: u128) -> u128 { - u128_checked_mul(lhs, rhs).expect('u128_mul Overflow') - } -} -impl U128MulEq of MulEq { - #[inline(always)] - fn mul_eq(ref self: u128, other: u128) { - self = Mul::mul(self, other); - } -} - -#[panic_with('u128 is 0', u128_as_non_zero)] -fn u128_try_as_non_zero(a: u128) -> Option> nopanic { - match u128_is_zero(a) { - IsZeroResult::Zero => Option::None, - IsZeroResult::NonZero(x) => Option::Some(x), - } -} - -pub(crate) impl U128TryIntoNonZero of TryInto> { - fn try_into(self: u128) -> Option> { - u128_try_as_non_zero(self) - } -} - -impl U128Div of Div { - fn div(lhs: u128, rhs: u128) -> u128 { - let (q, _r) = u128_safe_divmod(lhs, rhs.try_into().expect('Division by 0')); - q - } -} -impl U128DivEq of DivEq { - #[inline(always)] - fn div_eq(ref self: u128, other: u128) { - self = Div::div(self, other); - } -} - -impl U128Rem of Rem { - fn rem(lhs: u128, rhs: u128) -> u128 { - let (_q, r) = u128_safe_divmod(lhs, rhs.try_into().expect('Division by 0')); - r - } -} -impl U128RemEq of RemEq { - #[inline(always)] - fn rem_eq(ref self: u128, other: u128) { - self = Rem::rem(self, other); - } -} - -impl U128DivRem of DivRem { - fn div_rem(lhs: u128, rhs: NonZero) -> (u128, u128) { - u128_safe_divmod(lhs, rhs) - } -} - -pub extern fn u128_safe_divmod( - lhs: u128, rhs: NonZero -) -> (u128, u128) implicits(RangeCheck) nopanic; - -extern fn u128_eq(lhs: u128, rhs: u128) -> bool implicits() nopanic; - -impl U128PartialEq of PartialEq { - #[inline(always)] - fn eq(lhs: @u128, rhs: @u128) -> bool { - u128_eq(*lhs, *rhs) - } - #[inline(always)] - fn ne(lhs: @u128, rhs: @u128) -> bool { - !(*lhs == *rhs) - } -} - -impl U128PartialOrd of PartialOrd { - #[inline(always)] - fn le(lhs: u128, rhs: u128) -> bool { - u128_overflowing_sub(rhs, lhs).into_is_ok() - } - #[inline(always)] - fn ge(lhs: u128, rhs: u128) -> bool { - u128_overflowing_sub(lhs, rhs).into_is_ok() - } - #[inline(always)] - fn lt(lhs: u128, rhs: u128) -> bool { - u128_overflowing_sub(lhs, rhs).into_is_err() - } - #[inline(always)] - fn gt(lhs: u128, rhs: u128) -> bool { - u128_overflowing_sub(rhs, lhs).into_is_err() - } -} - -pub extern type Bitwise; -/// Returns the bitwise operations (AND, XOR, OR) between `lhs` and `rhs`. -extern fn bitwise(lhs: u128, rhs: u128) -> (u128, u128, u128) implicits(Bitwise) nopanic; -impl U128BitAnd of BitAnd { - #[inline(always)] - fn bitand(lhs: u128, rhs: u128) -> u128 { - let (v, _, _) = bitwise(lhs, rhs); - v - } -} -impl U128BitXor of BitXor { - #[inline(always)] - fn bitxor(lhs: u128, rhs: u128) -> u128 { - let (_, v, _) = bitwise(lhs, rhs); - v - } -} -impl U128BitOr of BitOr { - #[inline(always)] - fn bitor(lhs: u128, rhs: u128) -> u128 { - let (_, _, v) = bitwise(lhs, rhs); - v - } -} -impl U128BitNot of BitNot { - fn bitnot(a: u128) -> u128 { - BoundedInt::max() - a - } -} - -impl U128BitSize of core::num::traits::BitSize { - fn bits() -> usize { - 128 - } -} - -pub(crate) extern fn u128_is_zero(a: u128) -> IsZeroResult implicits() nopanic; - -pub extern fn u128_byte_reverse(input: u128) -> u128 implicits(Bitwise) nopanic; - -#[derive(Copy, Drop)] -pub extern type u8; -impl NumericLiteralu8 of NumericLiteral; -extern fn u8_to_felt252(a: u8) -> felt252 nopanic; - -#[panic_with('u8_from Overflow', u8_from_felt252)] -extern fn u8_try_from_felt252(a: felt252) -> Option implicits(RangeCheck) nopanic; - -extern fn u8_eq(lhs: u8, rhs: u8) -> bool implicits() nopanic; - -impl U8Serde = core::serde::into_felt252_based::SerdeImpl; - -impl U8PartialEq of PartialEq { - #[inline(always)] - fn eq(lhs: @u8, rhs: @u8) -> bool { - u8_eq(*lhs, *rhs) - } - #[inline(always)] - fn ne(lhs: @u8, rhs: @u8) -> bool { - !(*lhs == *rhs) - } -} - -impl U8PartialOrd of PartialOrd { - #[inline(always)] - fn le(lhs: u8, rhs: u8) -> bool { - u8_overflowing_sub(rhs, lhs).into_is_ok() - } - #[inline(always)] - fn ge(lhs: u8, rhs: u8) -> bool { - u8_overflowing_sub(lhs, rhs).into_is_ok() - } - #[inline(always)] - fn lt(lhs: u8, rhs: u8) -> bool { - u8_overflowing_sub(lhs, rhs).into_is_err() - } - #[inline(always)] - fn gt(lhs: u8, rhs: u8) -> bool { - u8_overflowing_sub(rhs, lhs).into_is_err() - } -} - -pub extern fn u8_overflowing_add(lhs: u8, rhs: u8) -> Result implicits(RangeCheck) nopanic; -pub extern fn u8_overflowing_sub(lhs: u8, rhs: u8) -> Result implicits(RangeCheck) nopanic; - -pub fn u8_wrapping_add(lhs: u8, rhs: u8) -> u8 implicits(RangeCheck) nopanic { - match u8_overflowing_add(lhs, rhs) { - Result::Ok(x) => x, - Result::Err(x) => x, - } -} - -pub fn u8_wrapping_sub(lhs: u8, rhs: u8) -> u8 implicits(RangeCheck) nopanic { - match u8_overflowing_sub(lhs, rhs) { - Result::Ok(x) => x, - Result::Err(x) => x, - } -} - -fn u8_checked_add(lhs: u8, rhs: u8) -> Option implicits(RangeCheck) nopanic { - match u8_overflowing_add(lhs, rhs) { - Result::Ok(r) => Option::Some(r), - Result::Err(_r) => Option::None, - } -} - -impl U8Add of Add { - fn add(lhs: u8, rhs: u8) -> u8 { - u8_overflowing_add(lhs, rhs).expect('u8_add Overflow') - } -} -impl U8AddEq of AddEq { - #[inline(always)] - fn add_eq(ref self: u8, other: u8) { - self = Add::add(self, other); - } -} - -fn u8_checked_sub(lhs: u8, rhs: u8) -> Option implicits(RangeCheck) nopanic { - match u8_overflowing_sub(lhs, rhs) { - Result::Ok(r) => Option::Some(r), - Result::Err(_r) => Option::None, - } -} - -impl U8Sub of Sub { - fn sub(lhs: u8, rhs: u8) -> u8 { - u8_overflowing_sub(lhs, rhs).expect('u8_sub Overflow') - } -} -impl U8SubEq of SubEq { - #[inline(always)] - fn sub_eq(ref self: u8, other: u8) { - self = Sub::sub(self, other); - } -} - -pub extern fn u8_wide_mul(lhs: u8, rhs: u8) -> u16 implicits() nopanic; -pub extern fn u8_sqrt(value: u8) -> u8 implicits(RangeCheck) nopanic; - -impl U8Mul of Mul { - fn mul(lhs: u8, rhs: u8) -> u8 { - u8_wide_mul(lhs, rhs).try_into().expect('u8_mul Overflow') - } -} -impl U8MulEq of MulEq { - #[inline(always)] - fn mul_eq(ref self: u8, other: u8) { - self = Mul::mul(self, other); - } -} - -extern fn u8_is_zero(a: u8) -> IsZeroResult implicits() nopanic; -pub extern fn u8_safe_divmod(lhs: u8, rhs: NonZero) -> (u8, u8) implicits(RangeCheck) nopanic; - -#[panic_with('u8 is 0', u8_as_non_zero)] -fn u8_try_as_non_zero(a: u8) -> Option> nopanic { - match u8_is_zero(a) { - IsZeroResult::Zero => Option::None, - IsZeroResult::NonZero(x) => Option::Some(x), - } -} - -impl U8TryIntoNonZero of TryInto> { - fn try_into(self: u8) -> Option> { - u8_try_as_non_zero(self) - } -} - -impl U8Div of Div { - fn div(lhs: u8, rhs: u8) -> u8 { - let (q, _r) = u8_safe_divmod(lhs, rhs.try_into().expect('Division by 0')); - q - } -} -impl U8DivEq of DivEq { - #[inline(always)] - fn div_eq(ref self: u8, other: u8) { - self = Div::div(self, other); - } -} - -impl U8Rem of Rem { - fn rem(lhs: u8, rhs: u8) -> u8 { - let (_q, r) = u8_safe_divmod(lhs, rhs.try_into().expect('Division by 0')); - r - } -} -impl U8RemEq of RemEq { - #[inline(always)] - fn rem_eq(ref self: u8, other: u8) { - self = Rem::rem(self, other); - } -} - -impl U8DivRem of DivRem { - fn div_rem(lhs: u8, rhs: NonZero) -> (u8, u8) { - u8_safe_divmod(lhs, rhs) - } -} - -impl U8BitNot of BitNot { - fn bitnot(a: u8) -> u8 { - BoundedInt::max() - a - } -} -extern fn u8_bitwise(lhs: u8, rhs: u8) -> (u8, u8, u8) implicits(Bitwise) nopanic; -impl U8BitAnd of BitAnd { - #[inline(always)] - fn bitand(lhs: u8, rhs: u8) -> u8 { - let (v, _, _) = u8_bitwise(lhs, rhs); - v - } -} -impl U8BitXor of BitXor { - #[inline(always)] - fn bitxor(lhs: u8, rhs: u8) -> u8 { - let (_, v, _) = u8_bitwise(lhs, rhs); - v - } -} -impl U8BitOr of BitOr { - #[inline(always)] - fn bitor(lhs: u8, rhs: u8) -> u8 { - let (_, _, v) = u8_bitwise(lhs, rhs); - v - } -} - -impl U8BitSize of core::num::traits::BitSize { - fn bits() -> usize { - 8 - } -} - -#[derive(Copy, Drop)] -pub extern type u16; -impl NumericLiteralu16 of NumericLiteral; -extern fn u16_to_felt252(a: u16) -> felt252 nopanic; - -#[panic_with('u16_from Overflow', u16_from_felt252)] -extern fn u16_try_from_felt252(a: felt252) -> Option implicits(RangeCheck) nopanic; - -extern fn u16_eq(lhs: u16, rhs: u16) -> bool implicits() nopanic; - -impl U16Serde = core::serde::into_felt252_based::SerdeImpl; - -impl U16PartialEq of PartialEq { - #[inline(always)] - fn eq(lhs: @u16, rhs: @u16) -> bool { - u16_eq(*lhs, *rhs) - } - #[inline(always)] - fn ne(lhs: @u16, rhs: @u16) -> bool { - !(*lhs == *rhs) - } -} - -impl U16PartialOrd of PartialOrd { - #[inline(always)] - fn le(lhs: u16, rhs: u16) -> bool { - u16_overflowing_sub(rhs, lhs).into_is_ok() - } - #[inline(always)] - fn ge(lhs: u16, rhs: u16) -> bool { - u16_overflowing_sub(lhs, rhs).into_is_ok() - } - #[inline(always)] - fn lt(lhs: u16, rhs: u16) -> bool { - u16_overflowing_sub(lhs, rhs).into_is_err() - } - #[inline(always)] - fn gt(lhs: u16, rhs: u16) -> bool { - u16_overflowing_sub(rhs, lhs).into_is_err() - } -} - -pub extern fn u16_overflowing_add( - lhs: u16, rhs: u16 -) -> Result implicits(RangeCheck) nopanic; -pub extern fn u16_overflowing_sub( - lhs: u16, rhs: u16 -) -> Result implicits(RangeCheck) nopanic; - -pub fn u16_wrapping_add(lhs: u16, rhs: u16) -> u16 implicits(RangeCheck) nopanic { - match u16_overflowing_add(lhs, rhs) { - Result::Ok(x) => x, - Result::Err(x) => x, - } -} - -pub fn u16_wrapping_sub(lhs: u16, rhs: u16) -> u16 implicits(RangeCheck) nopanic { - match u16_overflowing_sub(lhs, rhs) { - Result::Ok(x) => x, - Result::Err(x) => x, - } -} - -fn u16_checked_add(lhs: u16, rhs: u16) -> Option implicits(RangeCheck) nopanic { - match u16_overflowing_add(lhs, rhs) { - Result::Ok(r) => Option::Some(r), - Result::Err(_r) => Option::None, - } -} - -impl U16Add of Add { - fn add(lhs: u16, rhs: u16) -> u16 { - u16_overflowing_add(lhs, rhs).expect('u16_add Overflow') - } -} -impl U16AddEq of AddEq { - #[inline(always)] - fn add_eq(ref self: u16, other: u16) { - self = Add::add(self, other); - } -} - -fn u16_checked_sub(lhs: u16, rhs: u16) -> Option implicits(RangeCheck) nopanic { - match u16_overflowing_sub(lhs, rhs) { - Result::Ok(r) => Option::Some(r), - Result::Err(_r) => Option::None, - } -} - -impl U16Sub of Sub { - fn sub(lhs: u16, rhs: u16) -> u16 { - u16_overflowing_sub(lhs, rhs).expect('u16_sub Overflow') - } -} -impl U16SubEq of SubEq { - #[inline(always)] - fn sub_eq(ref self: u16, other: u16) { - self = Sub::sub(self, other); - } -} - -pub extern fn u16_wide_mul(lhs: u16, rhs: u16) -> u32 implicits() nopanic; -pub extern fn u16_sqrt(value: u16) -> u8 implicits(RangeCheck) nopanic; - -impl U16Mul of Mul { - fn mul(lhs: u16, rhs: u16) -> u16 { - u16_wide_mul(lhs, rhs).try_into().expect('u16_mul Overflow') - } -} -impl U16MulEq of MulEq { - #[inline(always)] - fn mul_eq(ref self: u16, other: u16) { - self = Mul::mul(self, other); - } -} - -extern fn u16_is_zero(a: u16) -> IsZeroResult implicits() nopanic; -pub extern fn u16_safe_divmod( - lhs: u16, rhs: NonZero -) -> (u16, u16) implicits(RangeCheck) nopanic; - -#[panic_with('u16 is 0', u16_as_non_zero)] -fn u16_try_as_non_zero(a: u16) -> Option> nopanic { - match u16_is_zero(a) { - IsZeroResult::Zero => Option::None, - IsZeroResult::NonZero(x) => Option::Some(x), - } -} - -impl U16TryIntoNonZero of TryInto> { - fn try_into(self: u16) -> Option> { - u16_try_as_non_zero(self) - } -} - -impl U16Div of Div { - fn div(lhs: u16, rhs: u16) -> u16 { - let (q, _r) = u16_safe_divmod(lhs, rhs.try_into().expect('Division by 0')); - q - } -} -impl U16DivEq of DivEq { - #[inline(always)] - fn div_eq(ref self: u16, other: u16) { - self = Div::div(self, other); - } -} - -impl U16Rem of Rem { - fn rem(lhs: u16, rhs: u16) -> u16 { - let (_q, r) = u16_safe_divmod(lhs, rhs.try_into().expect('Division by 0')); - r - } -} -impl U16RemEq of RemEq { - #[inline(always)] - fn rem_eq(ref self: u16, other: u16) { - self = Rem::rem(self, other); - } -} - -impl U16DivRem of DivRem { - fn div_rem(lhs: u16, rhs: NonZero) -> (u16, u16) { - u16_safe_divmod(lhs, rhs) - } -} - -impl U16BitNot of BitNot { - fn bitnot(a: u16) -> u16 { - BoundedInt::max() - a - } -} -extern fn u16_bitwise(lhs: u16, rhs: u16) -> (u16, u16, u16) implicits(Bitwise) nopanic; -impl U16BitAnd of BitAnd { - #[inline(always)] - fn bitand(lhs: u16, rhs: u16) -> u16 { - let (v, _, _) = u16_bitwise(lhs, rhs); - v - } -} -impl U16BitXor of BitXor { - #[inline(always)] - fn bitxor(lhs: u16, rhs: u16) -> u16 { - let (_, v, _) = u16_bitwise(lhs, rhs); - v - } -} -impl U16BitOr of BitOr { - #[inline(always)] - fn bitor(lhs: u16, rhs: u16) -> u16 { - let (_, _, v) = u16_bitwise(lhs, rhs); - v - } -} - -impl U16BitSize of core::num::traits::BitSize { - fn bits() -> usize { - 16 - } -} - -#[derive(Copy, Drop)] -pub extern type u32; -impl NumericLiteralu32 of NumericLiteral; -extern fn u32_to_felt252(a: u32) -> felt252 nopanic; - -#[panic_with('u32_from Overflow', u32_from_felt252)] -extern fn u32_try_from_felt252(a: felt252) -> Option implicits(RangeCheck) nopanic; - -extern fn u32_eq(lhs: u32, rhs: u32) -> bool implicits() nopanic; - -impl U32Serde = core::serde::into_felt252_based::SerdeImpl; - -impl U32PartialEq of PartialEq { - #[inline(always)] - fn eq(lhs: @u32, rhs: @u32) -> bool { - u32_eq(*lhs, *rhs) - } - #[inline(always)] - fn ne(lhs: @u32, rhs: @u32) -> bool { - !(*lhs == *rhs) - } -} - -impl U32PartialOrd of PartialOrd { - #[inline(always)] - fn le(lhs: u32, rhs: u32) -> bool { - u32_overflowing_sub(rhs, lhs).into_is_ok() - } - #[inline(always)] - fn ge(lhs: u32, rhs: u32) -> bool { - u32_overflowing_sub(lhs, rhs).into_is_ok() - } - #[inline(always)] - fn lt(lhs: u32, rhs: u32) -> bool { - u32_overflowing_sub(lhs, rhs).into_is_err() - } - #[inline(always)] - fn gt(lhs: u32, rhs: u32) -> bool { - u32_overflowing_sub(rhs, lhs).into_is_err() - } -} - -pub extern fn u32_overflowing_add( - lhs: u32, rhs: u32 -) -> Result implicits(RangeCheck) nopanic; -pub extern fn u32_overflowing_sub( - lhs: u32, rhs: u32 -) -> Result implicits(RangeCheck) nopanic; - -pub fn u32_wrapping_add(lhs: u32, rhs: u32) -> u32 implicits(RangeCheck) nopanic { - match u32_overflowing_add(lhs, rhs) { - Result::Ok(x) => x, - Result::Err(x) => x, - } -} - -pub fn u32_wrapping_sub(lhs: u32, rhs: u32) -> u32 implicits(RangeCheck) nopanic { - match u32_overflowing_sub(lhs, rhs) { - Result::Ok(x) => x, - Result::Err(x) => x, - } -} - -fn u32_checked_add(lhs: u32, rhs: u32) -> Option implicits(RangeCheck) nopanic { - match u32_overflowing_add(lhs, rhs) { - Result::Ok(r) => Option::Some(r), - Result::Err(_r) => Option::None, - } -} - -impl U32Add of Add { - fn add(lhs: u32, rhs: u32) -> u32 { - u32_overflowing_add(lhs, rhs).expect('u32_add Overflow') - } -} -impl U32AddEq of AddEq { - #[inline(always)] - fn add_eq(ref self: u32, other: u32) { - self = Add::add(self, other); - } -} - -fn u32_checked_sub(lhs: u32, rhs: u32) -> Option implicits(RangeCheck) nopanic { - match u32_overflowing_sub(lhs, rhs) { - Result::Ok(r) => Option::Some(r), - Result::Err(_r) => Option::None, - } -} - -impl U32Sub of Sub { - fn sub(lhs: u32, rhs: u32) -> u32 { - u32_overflowing_sub(lhs, rhs).expect('u32_sub Overflow') - } -} -impl U32SubEq of SubEq { - #[inline(always)] - fn sub_eq(ref self: u32, other: u32) { - self = Sub::sub(self, other); - } -} - -pub extern fn u32_wide_mul(lhs: u32, rhs: u32) -> u64 implicits() nopanic; -pub extern fn u32_sqrt(value: u32) -> u16 implicits(RangeCheck) nopanic; - -impl U32Mul of Mul { - fn mul(lhs: u32, rhs: u32) -> u32 { - u32_wide_mul(lhs, rhs).try_into().expect('u32_mul Overflow') - } -} -impl U32MulEq of MulEq { - #[inline(always)] - fn mul_eq(ref self: u32, other: u32) { - self = Mul::mul(self, other); - } -} - -extern fn u32_is_zero(a: u32) -> IsZeroResult implicits() nopanic; -pub extern fn u32_safe_divmod( - lhs: u32, rhs: NonZero -) -> (u32, u32) implicits(RangeCheck) nopanic; - -#[panic_with('u32 is 0', u32_as_non_zero)] -fn u32_try_as_non_zero(a: u32) -> Option> nopanic { - match u32_is_zero(a) { - IsZeroResult::Zero => Option::None, - IsZeroResult::NonZero(x) => Option::Some(x), - } -} - -pub(crate) impl U32TryIntoNonZero of TryInto> { - fn try_into(self: u32) -> Option> { - u32_try_as_non_zero(self) - } -} - -impl U32Div of Div { - fn div(lhs: u32, rhs: u32) -> u32 { - let (q, _r) = u32_safe_divmod(lhs, rhs.try_into().expect('Division by 0')); - q - } -} -impl U32DivEq of DivEq { - #[inline(always)] - fn div_eq(ref self: u32, other: u32) { - self = Div::div(self, other); - } -} - -impl U32Rem of Rem { - fn rem(lhs: u32, rhs: u32) -> u32 { - let (_q, r) = u32_safe_divmod(lhs, rhs.try_into().expect('Division by 0')); - r - } -} -impl U32RemEq of RemEq { - #[inline(always)] - fn rem_eq(ref self: u32, other: u32) { - self = Rem::rem(self, other); - } -} - -impl U32DivRem of DivRem { - fn div_rem(lhs: u32, rhs: NonZero) -> (u32, u32) { - u32_safe_divmod(lhs, rhs) - } -} - -impl U32BitNot of BitNot { - fn bitnot(a: u32) -> u32 { - BoundedInt::max() - a - } -} -extern fn u32_bitwise(lhs: u32, rhs: u32) -> (u32, u32, u32) implicits(Bitwise) nopanic; -impl U32BitAnd of BitAnd { - #[inline(always)] - fn bitand(lhs: u32, rhs: u32) -> u32 { - let (v, _, _) = u32_bitwise(lhs, rhs); - v - } -} -impl U32BitXor of BitXor { - #[inline(always)] - fn bitxor(lhs: u32, rhs: u32) -> u32 { - let (_, v, _) = u32_bitwise(lhs, rhs); - v - } -} -impl U32BitOr of BitOr { - #[inline(always)] - fn bitor(lhs: u32, rhs: u32) -> u32 { - let (_, _, v) = u32_bitwise(lhs, rhs); - v - } -} - -impl U32BitSize of core::num::traits::BitSize { - fn bits() -> usize { - 32 - } -} - -#[derive(Copy, Drop)] -pub extern type u64; -impl NumericLiteralu64 of NumericLiteral; -extern fn u64_to_felt252(a: u64) -> felt252 nopanic; - -#[panic_with('u64_from Overflow', u64_from_felt252)] -extern fn u64_try_from_felt252(a: felt252) -> Option implicits(RangeCheck) nopanic; - -extern fn u64_eq(lhs: u64, rhs: u64) -> bool implicits() nopanic; - -impl U64Serde = core::serde::into_felt252_based::SerdeImpl; - -impl U64PartialEq of PartialEq { - #[inline(always)] - fn eq(lhs: @u64, rhs: @u64) -> bool { - u64_eq(*lhs, *rhs) - } - #[inline(always)] - fn ne(lhs: @u64, rhs: @u64) -> bool { - !(*lhs == *rhs) - } -} - -impl U64PartialOrd of PartialOrd { - #[inline(always)] - fn le(lhs: u64, rhs: u64) -> bool { - u64_overflowing_sub(rhs, lhs).into_is_ok() - } - #[inline(always)] - fn ge(lhs: u64, rhs: u64) -> bool { - u64_overflowing_sub(lhs, rhs).into_is_ok() - } - #[inline(always)] - fn lt(lhs: u64, rhs: u64) -> bool { - u64_overflowing_sub(lhs, rhs).into_is_err() - } - #[inline(always)] - fn gt(lhs: u64, rhs: u64) -> bool { - u64_overflowing_sub(rhs, lhs).into_is_err() - } -} - -pub extern fn u64_overflowing_add( - lhs: u64, rhs: u64 -) -> Result implicits(RangeCheck) nopanic; -pub extern fn u64_overflowing_sub( - lhs: u64, rhs: u64 -) -> Result implicits(RangeCheck) nopanic; - -pub fn u64_wrapping_add(lhs: u64, rhs: u64) -> u64 implicits(RangeCheck) nopanic { - match u64_overflowing_add(lhs, rhs) { - Result::Ok(x) => x, - Result::Err(x) => x, - } -} - -pub fn u64_wrapping_sub(lhs: u64, rhs: u64) -> u64 implicits(RangeCheck) nopanic { - match u64_overflowing_sub(lhs, rhs) { - Result::Ok(x) => x, - Result::Err(x) => x, - } -} - -fn u64_checked_add(lhs: u64, rhs: u64) -> Option implicits(RangeCheck) nopanic { - match u64_overflowing_add(lhs, rhs) { - Result::Ok(r) => Option::Some(r), - Result::Err(_r) => Option::None, - } -} - -impl U64Add of Add { - fn add(lhs: u64, rhs: u64) -> u64 { - u64_overflowing_add(lhs, rhs).expect('u64_add Overflow') - } -} -impl U64AddEq of AddEq { - #[inline(always)] - fn add_eq(ref self: u64, other: u64) { - self = Add::add(self, other); - } -} - -fn u64_checked_sub(lhs: u64, rhs: u64) -> Option implicits(RangeCheck) nopanic { - match u64_overflowing_sub(lhs, rhs) { - Result::Ok(r) => Option::Some(r), - Result::Err(_r) => Option::None, - } -} - -impl U64Sub of Sub { - fn sub(lhs: u64, rhs: u64) -> u64 { - u64_overflowing_sub(lhs, rhs).expect('u64_sub Overflow') - } -} -impl U64SubEq of SubEq { - #[inline(always)] - fn sub_eq(ref self: u64, other: u64) { - self = Sub::sub(self, other); - } -} - -pub extern fn u64_wide_mul(lhs: u64, rhs: u64) -> u128 implicits() nopanic; -pub extern fn u64_sqrt(value: u64) -> u32 implicits(RangeCheck) nopanic; - -impl U64Mul of Mul { - fn mul(lhs: u64, rhs: u64) -> u64 { - u64_wide_mul(lhs, rhs).try_into().expect('u64_mul Overflow') - } -} -impl U64MulEq of MulEq { - #[inline(always)] - fn mul_eq(ref self: u64, other: u64) { - self = Mul::mul(self, other); - } -} - -extern fn u64_is_zero(a: u64) -> IsZeroResult implicits() nopanic; -pub extern fn u64_safe_divmod( - lhs: u64, rhs: NonZero -) -> (u64, u64) implicits(RangeCheck) nopanic; - -#[panic_with('u64 is 0', u64_as_non_zero)] -fn u64_try_as_non_zero(a: u64) -> Option> nopanic { - match u64_is_zero(a) { - IsZeroResult::Zero => Option::None, - IsZeroResult::NonZero(x) => Option::Some(x), - } -} - -impl U64TryIntoNonZero of TryInto> { - fn try_into(self: u64) -> Option> { - u64_try_as_non_zero(self) - } -} - -impl U64Div of Div { - fn div(lhs: u64, rhs: u64) -> u64 { - let (q, _r) = u64_safe_divmod(lhs, rhs.try_into().expect('Division by 0')); - q - } -} -impl U64DivEq of DivEq { - #[inline(always)] - fn div_eq(ref self: u64, other: u64) { - self = Div::div(self, other); - } -} - -impl U64Rem of Rem { - fn rem(lhs: u64, rhs: u64) -> u64 { - let (_q, r) = u64_safe_divmod(lhs, rhs.try_into().expect('Division by 0')); - r - } -} -impl U64RemEq of RemEq { - #[inline(always)] - fn rem_eq(ref self: u64, other: u64) { - self = Rem::rem(self, other); - } -} - -impl U64DivRem of DivRem { - fn div_rem(lhs: u64, rhs: NonZero) -> (u64, u64) { - u64_safe_divmod(lhs, rhs) - } -} - -impl U64BitNot of BitNot { - fn bitnot(a: u64) -> u64 { - BoundedInt::max() - a - } -} -extern fn u64_bitwise(lhs: u64, rhs: u64) -> (u64, u64, u64) implicits(Bitwise) nopanic; -impl U64BitAnd of BitAnd { - #[inline(always)] - fn bitand(lhs: u64, rhs: u64) -> u64 { - let (v, _, _) = u64_bitwise(lhs, rhs); - v - } -} -impl U64BitXor of BitXor { - #[inline(always)] - fn bitxor(lhs: u64, rhs: u64) -> u64 { - let (_, v, _) = u64_bitwise(lhs, rhs); - v - } -} -impl U64BitOr of BitOr { - #[inline(always)] - fn bitor(lhs: u64, rhs: u64) -> u64 { - let (_, _, v) = u64_bitwise(lhs, rhs); - v - } -} - -impl U64BitSize of core::num::traits::BitSize { - fn bits() -> usize { - 64 - } -} - -#[derive(Copy, Drop, Hash, PartialEq, Serde, starknet::Store)] -pub struct u256 { - pub low: u128, - pub high: u128, -} -impl NumericLiteralU256 of NumericLiteral; - -pub fn u256_overflowing_add(lhs: u256, rhs: u256) -> (u256, bool) implicits(RangeCheck) nopanic { - let (high, overflow) = match u128_overflowing_add(lhs.high, rhs.high) { - Result::Ok(high) => (high, false), - Result::Err(high) => (high, true), - }; - match u128_overflowing_add(lhs.low, rhs.low) { - Result::Ok(low) => (u256 { low, high }, overflow), - Result::Err(low) => { - match u128_overflowing_add(high, 1_u128) { - Result::Ok(high) => (u256 { low, high }, overflow), - Result::Err(high) => (u256 { low, high }, true), - } - }, - } -} - -pub fn u256_overflow_sub(lhs: u256, rhs: u256) -> (u256, bool) implicits(RangeCheck) nopanic { - let (high, overflow) = match u128_overflowing_sub(lhs.high, rhs.high) { - Result::Ok(high) => (high, false), - Result::Err(high) => (high, true), - }; - match u128_overflowing_sub(lhs.low, rhs.low) { - Result::Ok(low) => (u256 { low, high }, overflow), - Result::Err(low) => { - match u128_overflowing_sub(high, 1_u128) { - Result::Ok(high) => (u256 { low, high }, overflow), - Result::Err(high) => (u256 { low, high }, true), - } - }, - } -} - -pub fn u256_overflow_mul(lhs: u256, rhs: u256) -> (u256, bool) { - let (high1, low) = u128_wide_mul(lhs.low, rhs.low); - let (overflow_value1, high2) = u128_wide_mul(lhs.low, rhs.high); - let (overflow_value2, high3) = u128_wide_mul(lhs.high, rhs.low); - let (high, overflow) = match u128_overflowing_add(high1, high2) { - Result::Ok(high) => ( - high, - overflow_value1 != 0_u128 - || overflow_value2 != 0_u128 - || (lhs.high > 0_u128 && rhs.high > 0_u128) - ), - Result::Err(high) => (high, true), - }; - let (high, overflow) = match u128_overflowing_add(high, high3) { - Result::Ok(high) => (high, overflow), - Result::Err(high) => (high, true), - }; - (u256 { low, high }, overflow) -} - -fn u256_checked_add(lhs: u256, rhs: u256) -> Option implicits(RangeCheck) nopanic { - let (r, overflow) = u256_overflowing_add(lhs, rhs); - if overflow { - Option::None - } else { - Option::Some(r) - } -} - -impl U256Add of Add { - fn add(lhs: u256, rhs: u256) -> u256 { - u256_checked_add(lhs, rhs).expect('u256_add Overflow') - } -} -impl U256AddEq of AddEq { - #[inline(always)] - fn add_eq(ref self: u256, other: u256) { - self = Add::add(self, other); - } -} - -#[panic_with('u256_sub Overflow', u256_sub)] -fn u256_checked_sub(lhs: u256, rhs: u256) -> Option implicits(RangeCheck) nopanic { - let (r, overflow) = u256_overflow_sub(lhs, rhs); - if overflow { - Option::None - } else { - Option::Some(r) - } -} - -impl U256Sub of Sub { - fn sub(lhs: u256, rhs: u256) -> u256 { - u256_checked_sub(lhs, rhs).expect('u256_sub Overflow') - } -} -impl U256SubEq of SubEq { - #[inline(always)] - fn sub_eq(ref self: u256, other: u256) { - self = Sub::sub(self, other); - } -} - -fn u256_checked_mul(lhs: u256, rhs: u256) -> Option implicits(RangeCheck) { - let (r, overflow) = u256_overflow_mul(lhs, rhs); - if overflow { - Option::None - } else { - Option::Some(r) - } -} - -impl U256Mul of Mul { - fn mul(lhs: u256, rhs: u256) -> u256 { - u256_checked_mul(lhs, rhs).expect('u256_mul Overflow') - } -} -impl U256MulEq of MulEq { - #[inline(always)] - fn mul_eq(ref self: u256, other: u256) { - self = Mul::mul(self, other); - } -} - -impl U256PartialOrd of PartialOrd { - #[inline(always)] - fn le(lhs: u256, rhs: u256) -> bool { - !(rhs < lhs) - } - #[inline(always)] - fn ge(lhs: u256, rhs: u256) -> bool { - !(lhs < rhs) - } - fn lt(lhs: u256, rhs: u256) -> bool { - if lhs.high < rhs.high { - true - } else if lhs.high == rhs.high { - lhs.low < rhs.low - } else { - false - } - } - #[inline(always)] - fn gt(lhs: u256, rhs: u256) -> bool { - rhs < lhs - } -} - -impl U256BitAnd of BitAnd { - #[inline(always)] - fn bitand(lhs: u256, rhs: u256) -> u256 { - u256 { low: lhs.low & rhs.low, high: lhs.high & rhs.high } - } -} -impl U256BitXor of BitXor { - #[inline(always)] - fn bitxor(lhs: u256, rhs: u256) -> u256 { - u256 { low: lhs.low ^ rhs.low, high: lhs.high ^ rhs.high } - } -} -impl U256BitOr of BitOr { - #[inline(always)] - fn bitor(lhs: u256, rhs: u256) -> u256 { - u256 { low: lhs.low | rhs.low, high: lhs.high | rhs.high } - } -} - -fn u256_from_felt252(lhs: felt252) -> u256 implicits(RangeCheck) nopanic { - match u128s_from_felt252(lhs) { - U128sFromFelt252Result::Narrow(low) => u256 { low, high: 0_u128 }, - U128sFromFelt252Result::Wide((high, low)) => u256 { low, high }, - } -} - -extern fn u256_is_zero(a: u256) -> IsZeroResult implicits() nopanic; - -/// Calculates division with remainder of a u256 by a non-zero u256. -/// Additionally returns a `U128MulGuarantee` that is required for validating the calculation. -extern fn u256_safe_divmod( - lhs: u256, rhs: NonZero -) -> (u256, u256, U128MulGuarantee) implicits(RangeCheck) nopanic; - -/// Calculates division with remainder of a u256 by a non-zero u256. -#[inline(always)] -fn u256_safe_div_rem(lhs: u256, rhs: NonZero) -> (u256, u256) implicits(RangeCheck) nopanic { - let (q, r, _) = u256_safe_divmod(lhs, rhs); - (q, r) -} -pub extern fn u256_sqrt(a: u256) -> u128 implicits(RangeCheck) nopanic; - -#[panic_with('u256 is 0', u256_as_non_zero)] -fn u256_try_as_non_zero(a: u256) -> Option> nopanic { - match u256_is_zero(a) { - IsZeroResult::Zero => Option::None, - IsZeroResult::NonZero(x) => Option::Some(x), - } -} - -pub(crate) impl U256TryIntoNonZero of TryInto> { - fn try_into(self: u256) -> Option> { - u256_try_as_non_zero(self) - } -} - -impl U256Div of Div { - fn div(lhs: u256, rhs: u256) -> u256 { - let (q, _r) = u256_safe_div_rem(lhs, rhs.try_into().expect('Division by 0')); - q - } -} -impl U256DivEq of DivEq { - #[inline(always)] - fn div_eq(ref self: u256, other: u256) { - self = Div::div(self, other); - } -} - -impl U256Rem of Rem { - fn rem(lhs: u256, rhs: u256) -> u256 { - let (_q, r) = u256_safe_div_rem(lhs, rhs.try_into().expect('Division by 0')); - r - } -} -impl U256RemEq of RemEq { - #[inline(always)] - fn rem_eq(ref self: u256, other: u256) { - self = Rem::rem(self, other); - } -} - -impl U256DivRem of DivRem { - fn div_rem(lhs: u256, rhs: NonZero) -> (u256, u256) { - u256_safe_div_rem(lhs, rhs) - } -} - -impl U256BitNot of BitNot { - fn bitnot(a: u256) -> u256 { - u256 { low: ~a.low, high: ~a.high } - } -} - -impl U256BitSize of core::num::traits::BitSize { - fn bits() -> usize { - 256 - } -} - -#[derive(Copy, Drop, Hash, PartialEq, Serde)] -pub struct u512 { - pub limb0: u128, - pub limb1: u128, - pub limb2: u128, - pub limb3: u128, -} - -// Returns the result of u128 addition, including an overflow word. -fn u128_add_with_carry(a: u128, b: u128) -> (u128, u128) nopanic { - match u128_overflowing_add(a, b) { - Result::Ok(v) => (v, 0), - Result::Err(v) => (v, 1), - } -} - -pub fn u256_wide_mul(a: u256, b: u256) -> u512 nopanic { - let (limb1, limb0) = u128_wide_mul(a.low, b.low); - let (limb2, limb1_part) = u128_wide_mul(a.low, b.high); - let (limb1, limb1_overflow0) = u128_add_with_carry(limb1, limb1_part); - let (limb2_part, limb1_part) = u128_wide_mul(a.high, b.low); - let (limb1, limb1_overflow1) = u128_add_with_carry(limb1, limb1_part); - let (limb2, limb2_overflow) = u128_add_with_carry(limb2, limb2_part); - let (limb3, limb2_part) = u128_wide_mul(a.high, b.high); - // No overflow since no limb4. - let limb3 = u128_wrapping_add(limb3, limb2_overflow); - let (limb2, limb2_overflow) = u128_add_with_carry(limb2, limb2_part); - // No overflow since no limb4. - let limb3 = u128_wrapping_add(limb3, limb2_overflow); - // No overflow possible in this addition since both operands are 0/1. - let limb1_overflow = u128_wrapping_add(limb1_overflow0, limb1_overflow1); - let (limb2, limb2_overflow) = u128_add_with_carry(limb2, limb1_overflow); - // No overflow since no limb4. - let limb3 = u128_wrapping_add(limb3, limb2_overflow); - u512 { limb0, limb1, limb2, limb3 } -} - -/// Calculates division with remainder of a u512 by a non-zero u256. -#[inline(always)] -pub fn u512_safe_div_rem_by_u256( - lhs: u512, rhs: NonZero -) -> (u512, u256) implicits(RangeCheck) nopanic { - let (q, r, _, _, _, _, _) = u512_safe_divmod_by_u256(lhs, rhs); - (q, r) -} - -/// Calculates division with remainder of a u512 by a non-zero u256. -/// Additionally returns several `U128MulGuarantee`s that are required for validating the calculation. -extern fn u512_safe_divmod_by_u256( - lhs: u512, rhs: NonZero -) -> ( - u512, - u256, - U128MulGuarantee, - U128MulGuarantee, - U128MulGuarantee, - U128MulGuarantee, - U128MulGuarantee -) implicits(RangeCheck) nopanic; - -impl U512TryIntoU256 of TryInto { - fn try_into(self: u512) -> Option { - if self.limb2 != 0 || self.limb3 != 0 { - Option::None - } else { - Option::Some(u256 { low: self.limb0, high: self.limb1 }) - } - } -} - -/// Bounded -pub trait BoundedInt { - #[must_use] - fn min() -> T nopanic; - #[must_use] - fn max() -> T nopanic; -} - -impl BoundedU8 of BoundedInt { - #[inline(always)] - fn min() -> u8 nopanic { - 0_u8 - } - #[inline(always)] - fn max() -> u8 nopanic { - 0xff_u8 - } -} - -impl BoundedU16 of BoundedInt { - #[inline(always)] - fn min() -> u16 nopanic { - 0_u16 - } - #[inline(always)] - fn max() -> u16 nopanic { - 0xffff_u16 - } -} - -impl BoundedU32 of BoundedInt { - #[inline(always)] - fn min() -> u32 nopanic { - 0_u32 - } - #[inline(always)] - fn max() -> u32 nopanic { - 0xffffffff_u32 - } -} - -impl BoundedU64 of BoundedInt { - #[inline(always)] - fn min() -> u64 nopanic { - 0_u64 - } - #[inline(always)] - fn max() -> u64 nopanic { - 0xffffffffffffffff_u64 - } -} - -impl BoundedU128 of BoundedInt { - #[inline(always)] - fn min() -> u128 nopanic { - 0_u128 - } - #[inline(always)] - fn max() -> u128 nopanic { - 0xffffffffffffffffffffffffffffffff_u128 - } -} - -impl BoundedU256 of BoundedInt { - #[inline(always)] - fn min() -> u256 nopanic { - 0_u256 - } - #[inline(always)] - fn max() -> u256 nopanic { - u256 { low: BoundedInt::max(), high: BoundedInt::max() } - } -} - -impl BoundedI8 of BoundedInt { - #[inline(always)] - fn min() -> i8 nopanic { - -0x80 - } - #[inline(always)] - fn max() -> i8 nopanic { - 0x7f - } -} - -impl BoundedI16 of BoundedInt { - #[inline(always)] - fn min() -> i16 nopanic { - -0x8000 - } - #[inline(always)] - fn max() -> i16 nopanic { - 0x7fff - } -} - -impl BoundedI32 of BoundedInt { - #[inline(always)] - fn min() -> i32 nopanic { - -0x80000000 - } - #[inline(always)] - fn max() -> i32 nopanic { - 0x7fffffff - } -} - -impl BoundedI64 of BoundedInt { - #[inline(always)] - fn min() -> i64 nopanic { - -0x8000000000000000 - } - #[inline(always)] - fn max() -> i64 nopanic { - 0x7fffffffffffffff - } -} - -impl BoundedI128 of BoundedInt { - #[inline(always)] - fn min() -> i128 nopanic { - -0x80000000000000000000000000000000 - } - #[inline(always)] - fn max() -> i128 nopanic { - 0x7fffffffffffffffffffffffffffffff - } -} - -/// Conversions. -pub(crate) impl Felt252TryIntoU8 of TryInto { - fn try_into(self: felt252) -> Option { - u8_try_from_felt252(self) - } -} -pub(crate) impl U8IntoFelt252 of Into { - fn into(self: u8) -> felt252 { - u8_to_felt252(self) - } -} -pub(crate) impl Felt252TryIntoU16 of TryInto { - fn try_into(self: felt252) -> Option { - u16_try_from_felt252(self) - } -} -pub(crate) impl U16IntoFelt252 of Into { - fn into(self: u16) -> felt252 { - u16_to_felt252(self) - } -} -pub(crate) impl Felt252TryIntoU32 of TryInto { - fn try_into(self: felt252) -> Option { - u32_try_from_felt252(self) - } -} -pub(crate) impl U32IntoFelt252 of Into { - fn into(self: u32) -> felt252 { - u32_to_felt252(self) - } -} -pub(crate) impl Felt252TryIntoU64 of TryInto { - fn try_into(self: felt252) -> Option { - u64_try_from_felt252(self) - } -} -pub(crate) impl U64IntoFelt252 of Into { - fn into(self: u64) -> felt252 { - u64_to_felt252(self) - } -} -pub(crate) impl Felt252TryIntoU128 of TryInto { - fn try_into(self: felt252) -> Option { - u128_try_from_felt252(self) - } -} -pub(crate) impl U128IntoFelt252 of Into { - fn into(self: u128) -> felt252 { - u128_to_felt252(self) - } -} -pub(crate) impl Felt252IntoU256 of Into { - fn into(self: felt252) -> u256 { - u256_from_felt252(self) - } -} -pub(crate) impl U256TryIntoFelt252 of TryInto { - fn try_into(self: u256) -> Option { - let FELT252_PRIME_HIGH = 0x8000000000000110000000000000000_u128; - if self.high > FELT252_PRIME_HIGH { - return Option::None; - } - if self.high == FELT252_PRIME_HIGH { - // since FELT252_PRIME_LOW is 1. - if self.low != 0 { - return Option::None; - } - } - Option::Some( - self.high.into() * 0x100000000000000000000000000000000_felt252 + self.low.into() - ) - } -} -impl Felt252TryIntoI8 of TryInto { - fn try_into(self: felt252) -> Option { - i8_try_from_felt252(self) - } -} -pub(crate) impl I8IntoFelt252 of Into { - fn into(self: i8) -> felt252 { - i8_to_felt252(self) - } -} -impl Felt252TryIntoI16 of TryInto { - fn try_into(self: felt252) -> Option { - i16_try_from_felt252(self) - } -} -pub(crate) impl I16IntoFelt252 of Into { - fn into(self: i16) -> felt252 { - i16_to_felt252(self) - } -} -impl Felt252TryIntoI32 of TryInto { - fn try_into(self: felt252) -> Option { - i32_try_from_felt252(self) - } -} -pub(crate) impl I32IntoFelt252 of Into { - fn into(self: i32) -> felt252 { - i32_to_felt252(self) - } -} -impl Felt252TryIntoI64 of TryInto { - fn try_into(self: felt252) -> Option { - i64_try_from_felt252(self) - } -} -pub(crate) impl I64IntoFelt252 of Into { - fn into(self: i64) -> felt252 { - i64_to_felt252(self) - } -} -impl Felt252TryIntoI128 of TryInto { - fn try_into(self: felt252) -> Option { - i128_try_from_felt252(self) - } -} -pub(crate) impl I128IntoFelt252 of Into { - fn into(self: i128) -> felt252 { - i128_to_felt252(self) - } -} - -// TODO(lior): Restrict the function (using traits) in the high-level compiler so that wrong types -// will not lead to Sierra errors. -pub(crate) extern fn upcast(x: FromType) -> ToType nopanic; - -// TODO(lior): Restrict the function (using traits) in the high-level compiler so that wrong types -// will not lead to Sierra errors. -extern fn downcast(x: FromType) -> Option implicits(RangeCheck) nopanic; - -// Marks `FromType` as upcastable to `ToType`. -// Do not add user code implementing this trait. -trait Upcastable; -impl UpcastableU8U16 of Upcastable; -impl UpcastableU8I16 of Upcastable; -impl UpcastableU8U32 of Upcastable; -impl UpcastableU8I32 of Upcastable; -impl UpcastableU8U64 of Upcastable; -impl UpcastableU8I64 of Upcastable; -impl UpcastableU8U128 of Upcastable; -impl UpcastableU8I128 of Upcastable; -impl UpcastableI8I16 of Upcastable; -impl UpcastableI8I32 of Upcastable; -impl UpcastableI8I64 of Upcastable; -impl UpcastableI8I128 of Upcastable; -impl UpcastableU16U32 of Upcastable; -impl UpcastableU16I32 of Upcastable; -impl UpcastableU16U64 of Upcastable; -impl UpcastableU16I64 of Upcastable; -impl UpcastableU16U128 of Upcastable; -impl UpcastableU16I128 of Upcastable; -impl UpcastableI16I32 of Upcastable; -impl UpcastableI16I64 of Upcastable; -impl UpcastableI16I128 of Upcastable; -impl UpcastableU32U64 of Upcastable; -impl UpcastableU32I64 of Upcastable; -impl UpcastableU32U128 of Upcastable; -impl UpcastableU32I128 of Upcastable; -impl UpcastableI32I64 of Upcastable; -impl UpcastableI32I128 of Upcastable; -impl UpcastableU64U128 of Upcastable; -impl UpcastableU64I128 of Upcastable; -impl UpcastableI64I128 of Upcastable; -// Marks a type as an int that is downcastable to other downcastable ints. -// Do not add user code implementing this trait. -trait DowncastableInt; -impl DowncastableU8 of DowncastableInt; -impl DowncastableI8 of DowncastableInt; -impl DowncastableU16 of DowncastableInt; -impl DowncastableI16 of DowncastableInt; -impl DowncastableU32 of DowncastableInt; -impl DowncastableI32 of DowncastableInt; -impl DowncastableU64 of DowncastableInt; -impl DowncastableI64 of DowncastableInt; -impl DowncastableU128 of DowncastableInt; -impl DowncastableI128 of DowncastableInt; - - -/// Default values -impl U8Default of Default { - #[inline(always)] - fn default() -> u8 nopanic { - 0_u8 - } -} - -impl U16Default of Default { - #[inline(always)] - fn default() -> u16 nopanic { - 0_u16 - } -} - -impl U32Default of Default { - #[inline(always)] - fn default() -> u32 nopanic { - 0_u32 - } -} - -impl U64Default of Default { - #[inline(always)] - fn default() -> u64 nopanic { - 0_u64 - } -} - -impl U128Default of Default { - #[inline(always)] - fn default() -> u128 nopanic { - 0_u128 - } -} - -impl U256Default of Default { - #[inline(always)] - fn default() -> u256 nopanic { - 0_u256 - } -} - - -/// Default values for felt252_dict values. -impl U8Felt252DictValue of Felt252DictValue { - #[inline(always)] - fn zero_default() -> u8 nopanic { - 0 - } -} - -impl U16Felt252DictValue of Felt252DictValue { - #[inline(always)] - fn zero_default() -> u16 nopanic { - 0 - } -} - -impl U32Felt252DictValue of Felt252DictValue { - #[inline(always)] - fn zero_default() -> u32 nopanic { - 0 - } -} - -impl U64Felt252DictValue of Felt252DictValue { - #[inline(always)] - fn zero_default() -> u64 nopanic { - 0 - } -} - -impl U128Felt252DictValue of Felt252DictValue { - #[inline(always)] - fn zero_default() -> u128 nopanic { - 0 - } -} - -impl UpcastableInto> of Into { - fn into(self: From) -> To { - upcast(self) - } -} - -impl DowncastableIntTryInto< - From, To, +DowncastableInt, +DowncastableInt, -Into -> of TryInto { - fn try_into(self: From) -> Option { - downcast(self) - } -} - -impl U8IntoU256 of Into { - fn into(self: u8) -> u256 { - u256 { low: upcast(self), high: 0_u128 } - } -} - -impl U256TryIntoU8 of TryInto { - fn try_into(self: u256) -> Option { - let u256 { low, high } = self; - - if high != 0 { - return Option::None; - } - - low.try_into() - } -} - -impl U16IntoU256 of Into { - fn into(self: u16) -> u256 { - u256 { low: upcast(self), high: 0_u128 } - } -} - -impl U256TryIntoU16 of TryInto { - fn try_into(self: u256) -> Option { - let u256 { low, high } = self; - - if high != 0 { - return Option::None; - } - - low.try_into() - } -} - -impl U32IntoU256 of Into { - fn into(self: u32) -> u256 { - u256 { low: upcast(self), high: 0_u128 } - } -} - -impl U256TryIntoU32 of TryInto { - fn try_into(self: u256) -> Option { - let u256 { low, high } = self; - - if high != 0 { - return Option::None; - } - - low.try_into() - } -} - -impl U64IntoU256 of Into { - fn into(self: u64) -> u256 { - u256 { low: upcast(self), high: 0_u128 } - } -} - -impl U256TryIntoU64 of TryInto { - fn try_into(self: u256) -> Option { - let u256 { low, high } = self; - - if high != 0 { - return Option::None; - } - - low.try_into() - } -} - -impl U128IntoU256 of Into { - fn into(self: u128) -> u256 { - u256 { low: self, high: 0_u128 } - } -} - -impl U256TryIntoU128 of TryInto { - fn try_into(self: u256) -> Option { - let u256 { low, high } = self; - - if high != 0 { - return Option::None; - } - - Option::Some(low) - } -} - -enum SignedIntegerResult { - InRange: T, - Underflow: T, - Overflow: T, -} -impl SignedIntegerResultDrop> of Drop>; - -#[derive(Copy, Drop)] -pub extern type i8; -impl NumericLiterali8 of NumericLiteral; -extern fn i8_try_from_felt252(a: felt252) -> Option implicits(RangeCheck) nopanic; -extern fn i8_to_felt252(a: i8) -> felt252 nopanic; - -extern fn i8_is_zero(a: i8) -> IsZeroResult implicits() nopanic; -extern fn i8_eq(lhs: i8, rhs: i8) -> bool implicits() nopanic; - -impl I8Serde = core::serde::into_felt252_based::SerdeImpl; - -impl I8PartialEq of PartialEq { - #[inline(always)] - fn eq(lhs: @i8, rhs: @i8) -> bool { - i8_eq(*lhs, *rhs) - } - #[inline(always)] - fn ne(lhs: @i8, rhs: @i8) -> bool { - !(*lhs == *rhs) - } -} - -extern fn i8_overflowing_add_impl( - lhs: i8, rhs: i8 -) -> SignedIntegerResult implicits(RangeCheck) nopanic; -extern fn i8_overflowing_sub_impl( - lhs: i8, rhs: i8 -) -> SignedIntegerResult implicits(RangeCheck) nopanic; -impl I8Add of Add { - fn add(lhs: i8, rhs: i8) -> i8 { - match i8_overflowing_add_impl(lhs, rhs) { - SignedIntegerResult::InRange(result) => result, - SignedIntegerResult::Underflow(_) => core::panic_with_felt252('i8_add Underflow'), - SignedIntegerResult::Overflow(_) => core::panic_with_felt252('i8_add Overflow'), - } - } -} -impl I8AddEq of AddEq { - #[inline(always)] - fn add_eq(ref self: i8, other: i8) { - self = Add::add(self, other); - } -} -impl I8Sub of Sub { - fn sub(lhs: i8, rhs: i8) -> i8 { - match i8_overflowing_sub_impl(lhs, rhs) { - SignedIntegerResult::InRange(result) => result, - SignedIntegerResult::Underflow(_) => core::panic_with_felt252('i8_sub Underflow'), - SignedIntegerResult::Overflow(_) => core::panic_with_felt252('i8_sub Overflow'), - } - } -} -impl I8SubEq of SubEq { - #[inline(always)] - fn sub_eq(ref self: i8, other: i8) { - self = Sub::sub(self, other); - } -} - -impl I8Neg of Neg { - #[inline(always)] - fn neg(a: i8) -> i8 { - 0 - a - } -} - -pub extern fn i8_wide_mul(lhs: i8, rhs: i8) -> i16 implicits() nopanic; -impl I8Mul of Mul { - fn mul(lhs: i8, rhs: i8) -> i8 { - i8_wide_mul(lhs, rhs).try_into().expect('i8_mul Overflow') - } -} -impl I8MulEq of MulEq { - #[inline(always)] - fn mul_eq(ref self: i8, other: i8) { - self = Mul::mul(self, other); - } -} - -/// If `lhs` >= `rhs` returns `Ok(lhs - rhs)` else returns `Err(2**8 + lhs - rhs)`. -pub extern fn i8_diff(lhs: i8, rhs: i8) -> Result implicits(RangeCheck) nopanic; -impl I8PartialOrd of PartialOrd { - #[inline(always)] - fn le(lhs: i8, rhs: i8) -> bool { - i8_diff(rhs, lhs).into_is_ok() - } - #[inline(always)] - fn ge(lhs: i8, rhs: i8) -> bool { - i8_diff(lhs, rhs).into_is_ok() - } - #[inline(always)] - fn lt(lhs: i8, rhs: i8) -> bool { - i8_diff(lhs, rhs).into_is_err() - } - #[inline(always)] - fn gt(lhs: i8, rhs: i8) -> bool { - i8_diff(rhs, lhs).into_is_err() - } -} - -impl I8BitSize of core::num::traits::BitSize { - fn bits() -> usize { - 8 - } -} - -#[derive(Copy, Drop)] -pub extern type i16; -impl NumericLiterali16 of NumericLiteral; -extern fn i16_try_from_felt252(a: felt252) -> Option implicits(RangeCheck) nopanic; -extern fn i16_to_felt252(a: i16) -> felt252 nopanic; - -extern fn i16_is_zero(a: i16) -> IsZeroResult implicits() nopanic; -extern fn i16_eq(lhs: i16, rhs: i16) -> bool implicits() nopanic; - -impl I16Serde = core::serde::into_felt252_based::SerdeImpl; - -impl I16PartialEq of PartialEq { - #[inline(always)] - fn eq(lhs: @i16, rhs: @i16) -> bool { - i16_eq(*lhs, *rhs) - } - #[inline(always)] - fn ne(lhs: @i16, rhs: @i16) -> bool { - !(*lhs == *rhs) - } -} - -extern fn i16_overflowing_add_impl( - lhs: i16, rhs: i16 -) -> SignedIntegerResult implicits(RangeCheck) nopanic; -extern fn i16_overflowing_sub_impl( - lhs: i16, rhs: i16 -) -> SignedIntegerResult implicits(RangeCheck) nopanic; -impl I16Add of Add { - fn add(lhs: i16, rhs: i16) -> i16 { - match i16_overflowing_add_impl(lhs, rhs) { - SignedIntegerResult::InRange(result) => result, - SignedIntegerResult::Underflow(_) => core::panic_with_felt252('i16_add Underflow'), - SignedIntegerResult::Overflow(_) => core::panic_with_felt252('i16_add Overflow'), - } - } -} -impl I16AddEq of AddEq { - #[inline(always)] - fn add_eq(ref self: i16, other: i16) { - self = Add::add(self, other); - } -} -impl I16Sub of Sub { - fn sub(lhs: i16, rhs: i16) -> i16 { - match i16_overflowing_sub_impl(lhs, rhs) { - SignedIntegerResult::InRange(result) => result, - SignedIntegerResult::Underflow(_) => core::panic_with_felt252('i16_sub Underflow'), - SignedIntegerResult::Overflow(_) => core::panic_with_felt252('i16_sub Overflow'), - } - } -} -impl I16SubEq of SubEq { - #[inline(always)] - fn sub_eq(ref self: i16, other: i16) { - self = Sub::sub(self, other); - } -} - -impl I16Neg of Neg { - #[inline(always)] - fn neg(a: i16) -> i16 { - 0 - a - } -} - -pub extern fn i16_wide_mul(lhs: i16, rhs: i16) -> i32 implicits() nopanic; -impl I16Mul of Mul { - fn mul(lhs: i16, rhs: i16) -> i16 { - i16_wide_mul(lhs, rhs).try_into().expect('i16_mul Overflow') - } -} -impl I16MulEq of MulEq { - #[inline(always)] - fn mul_eq(ref self: i16, other: i16) { - self = Mul::mul(self, other); - } -} - -/// If `lhs` >= `rhs` returns `Ok(lhs - rhs)` else returns `Err(2**16 + lhs - rhs)`. -pub extern fn i16_diff(lhs: i16, rhs: i16) -> Result implicits(RangeCheck) nopanic; -impl I16PartialOrd of PartialOrd { - #[inline(always)] - fn le(lhs: i16, rhs: i16) -> bool { - i16_diff(rhs, lhs).into_is_ok() - } - #[inline(always)] - fn ge(lhs: i16, rhs: i16) -> bool { - i16_diff(lhs, rhs).into_is_ok() - } - #[inline(always)] - fn lt(lhs: i16, rhs: i16) -> bool { - i16_diff(lhs, rhs).into_is_err() - } - #[inline(always)] - fn gt(lhs: i16, rhs: i16) -> bool { - i16_diff(rhs, lhs).into_is_err() - } -} - -impl I16BitSize of core::num::traits::BitSize { - fn bits() -> usize { - 16 - } -} - -#[derive(Copy, Drop)] -pub extern type i32; -impl NumericLiterali32 of NumericLiteral; -extern fn i32_try_from_felt252(a: felt252) -> Option implicits(RangeCheck) nopanic; -extern fn i32_to_felt252(a: i32) -> felt252 nopanic; - -extern fn i32_is_zero(a: i32) -> IsZeroResult implicits() nopanic; -extern fn i32_eq(lhs: i32, rhs: i32) -> bool implicits() nopanic; - -impl I32Serde = core::serde::into_felt252_based::SerdeImpl; - -impl I32PartialEq of PartialEq { - #[inline(always)] - fn eq(lhs: @i32, rhs: @i32) -> bool { - i32_eq(*lhs, *rhs) - } - #[inline(always)] - fn ne(lhs: @i32, rhs: @i32) -> bool { - !(*lhs == *rhs) - } -} - -extern fn i32_overflowing_add_impl( - lhs: i32, rhs: i32 -) -> SignedIntegerResult implicits(RangeCheck) nopanic; -extern fn i32_overflowing_sub_impl( - lhs: i32, rhs: i32 -) -> SignedIntegerResult implicits(RangeCheck) nopanic; -impl I32Add of Add { - fn add(lhs: i32, rhs: i32) -> i32 { - match i32_overflowing_add_impl(lhs, rhs) { - SignedIntegerResult::InRange(result) => result, - SignedIntegerResult::Underflow(_) => core::panic_with_felt252('i32_add Underflow'), - SignedIntegerResult::Overflow(_) => core::panic_with_felt252('i32_add Overflow'), - } - } -} -impl I32AddEq of AddEq { - #[inline(always)] - fn add_eq(ref self: i32, other: i32) { - self = Add::add(self, other); - } -} -impl I32Sub of Sub { - fn sub(lhs: i32, rhs: i32) -> i32 { - match i32_overflowing_sub_impl(lhs, rhs) { - SignedIntegerResult::InRange(result) => result, - SignedIntegerResult::Underflow(_) => core::panic_with_felt252('i32_sub Underflow'), - SignedIntegerResult::Overflow(_) => core::panic_with_felt252('i32_sub Overflow'), - } - } -} -impl I32SubEq of SubEq { - #[inline(always)] - fn sub_eq(ref self: i32, other: i32) { - self = Sub::sub(self, other); - } -} - -impl I32Neg of Neg { - #[inline(always)] - fn neg(a: i32) -> i32 { - 0 - a - } -} - -pub extern fn i32_wide_mul(lhs: i32, rhs: i32) -> i64 implicits() nopanic; -impl I32Mul of Mul { - fn mul(lhs: i32, rhs: i32) -> i32 { - i32_wide_mul(lhs, rhs).try_into().expect('i32_mul Overflow') - } -} -impl I32MulEq of MulEq { - #[inline(always)] - fn mul_eq(ref self: i32, other: i32) { - self = Mul::mul(self, other); - } -} - -/// If `lhs` >= `rhs` returns `Ok(lhs - rhs)` else returns `Err(2**32 + lhs - rhs)`. -pub extern fn i32_diff(lhs: i32, rhs: i32) -> Result implicits(RangeCheck) nopanic; -impl I32PartialOrd of PartialOrd { - #[inline(always)] - fn le(lhs: i32, rhs: i32) -> bool { - i32_diff(rhs, lhs).into_is_ok() - } - #[inline(always)] - fn ge(lhs: i32, rhs: i32) -> bool { - i32_diff(lhs, rhs).into_is_ok() - } - #[inline(always)] - fn lt(lhs: i32, rhs: i32) -> bool { - i32_diff(lhs, rhs).into_is_err() - } - #[inline(always)] - fn gt(lhs: i32, rhs: i32) -> bool { - i32_diff(rhs, lhs).into_is_err() - } -} - -impl I32BitSize of core::num::traits::BitSize { - fn bits() -> usize { - 32 - } -} - -#[derive(Copy, Drop)] -pub extern type i64; -impl NumericLiterali64 of NumericLiteral; -extern fn i64_try_from_felt252(a: felt252) -> Option implicits(RangeCheck) nopanic; -extern fn i64_to_felt252(a: i64) -> felt252 nopanic; - -extern fn i64_is_zero(a: i64) -> IsZeroResult implicits() nopanic; -extern fn i64_eq(lhs: i64, rhs: i64) -> bool implicits() nopanic; - -impl I64Serde = core::serde::into_felt252_based::SerdeImpl; - -impl I64PartialEq of PartialEq { - #[inline(always)] - fn eq(lhs: @i64, rhs: @i64) -> bool { - i64_eq(*lhs, *rhs) - } - #[inline(always)] - fn ne(lhs: @i64, rhs: @i64) -> bool { - !(*lhs == *rhs) - } -} - -extern fn i64_overflowing_add_impl( - lhs: i64, rhs: i64 -) -> SignedIntegerResult implicits(RangeCheck) nopanic; -extern fn i64_overflowing_sub_impl( - lhs: i64, rhs: i64 -) -> SignedIntegerResult implicits(RangeCheck) nopanic; -impl I64Add of Add { - fn add(lhs: i64, rhs: i64) -> i64 { - match i64_overflowing_add_impl(lhs, rhs) { - SignedIntegerResult::InRange(result) => result, - SignedIntegerResult::Underflow(_) => core::panic_with_felt252('i64_add Underflow'), - SignedIntegerResult::Overflow(_) => core::panic_with_felt252('i64_add Overflow'), - } - } -} -impl I64AddEq of AddEq { - #[inline(always)] - fn add_eq(ref self: i64, other: i64) { - self = Add::add(self, other); - } -} -impl I64Sub of Sub { - fn sub(lhs: i64, rhs: i64) -> i64 { - match i64_overflowing_sub_impl(lhs, rhs) { - SignedIntegerResult::InRange(result) => result, - SignedIntegerResult::Underflow(_) => core::panic_with_felt252('i64_sub Underflow'), - SignedIntegerResult::Overflow(_) => core::panic_with_felt252('i64_sub Overflow'), - } - } -} -impl I64SubEq of SubEq { - #[inline(always)] - fn sub_eq(ref self: i64, other: i64) { - self = Sub::sub(self, other); - } -} - -impl I64Neg of Neg { - #[inline(always)] - fn neg(a: i64) -> i64 { - 0 - a - } -} - -pub extern fn i64_wide_mul(lhs: i64, rhs: i64) -> i128 implicits() nopanic; -impl I64Mul of Mul { - fn mul(lhs: i64, rhs: i64) -> i64 { - i64_wide_mul(lhs, rhs).try_into().expect('i64_mul Overflow') - } -} -impl I64MulEq of MulEq { - #[inline(always)] - fn mul_eq(ref self: i64, other: i64) { - self = Mul::mul(self, other); - } -} - -/// If `lhs` >= `rhs` returns `Ok(lhs - rhs)` else returns `Err(2**64 + lhs - rhs)`. -pub extern fn i64_diff(lhs: i64, rhs: i64) -> Result implicits(RangeCheck) nopanic; -impl I64PartialOrd of PartialOrd { - #[inline(always)] - fn le(lhs: i64, rhs: i64) -> bool { - i64_diff(rhs, lhs).into_is_ok() - } - #[inline(always)] - fn ge(lhs: i64, rhs: i64) -> bool { - i64_diff(lhs, rhs).into_is_ok() - } - #[inline(always)] - fn lt(lhs: i64, rhs: i64) -> bool { - i64_diff(lhs, rhs).into_is_err() - } - #[inline(always)] - fn gt(lhs: i64, rhs: i64) -> bool { - i64_diff(rhs, lhs).into_is_err() - } -} - -impl I64BitSize of core::num::traits::BitSize { - fn bits() -> usize { - 64 - } -} - -#[derive(Copy, Drop)] -pub extern type i128; -impl NumericLiterali128 of NumericLiteral; -extern fn i128_try_from_felt252(a: felt252) -> Option implicits(RangeCheck) nopanic; -extern fn i128_to_felt252(a: i128) -> felt252 nopanic; - -extern fn i128_is_zero(a: i128) -> IsZeroResult implicits() nopanic; -extern fn i128_eq(lhs: i128, rhs: i128) -> bool implicits() nopanic; - -impl I128Serde = core::serde::into_felt252_based::SerdeImpl; - -impl I128PartialEq of PartialEq { - #[inline(always)] - fn eq(lhs: @i128, rhs: @i128) -> bool { - i128_eq(*lhs, *rhs) - } - #[inline(always)] - fn ne(lhs: @i128, rhs: @i128) -> bool { - !(*lhs == *rhs) - } -} - -extern fn i128_overflowing_add_impl( - lhs: i128, rhs: i128 -) -> SignedIntegerResult implicits(RangeCheck) nopanic; -extern fn i128_overflowing_sub_impl( - lhs: i128, rhs: i128 -) -> SignedIntegerResult implicits(RangeCheck) nopanic; -impl I128Add of Add { - fn add(lhs: i128, rhs: i128) -> i128 { - match i128_overflowing_add_impl(lhs, rhs) { - SignedIntegerResult::InRange(result) => result, - SignedIntegerResult::Underflow(_) => core::panic_with_felt252('i128_add Underflow'), - SignedIntegerResult::Overflow(_) => core::panic_with_felt252('i128_add Overflow'), - } - } -} -impl I128AddEq of AddEq { - #[inline(always)] - fn add_eq(ref self: i128, other: i128) { - self = Add::add(self, other); - } -} -impl I128Sub of Sub { - fn sub(lhs: i128, rhs: i128) -> i128 { - match i128_overflowing_sub_impl(lhs, rhs) { - SignedIntegerResult::InRange(result) => result, - SignedIntegerResult::Underflow(_) => core::panic_with_felt252('i128_sub Underflow'), - SignedIntegerResult::Overflow(_) => core::panic_with_felt252('i128_sub Overflow'), - } - } -} -impl I128SubEq of SubEq { - #[inline(always)] - fn sub_eq(ref self: i128, other: i128) { - self = Sub::sub(self, other); - } -} - -impl I128Neg of Neg { - #[inline(always)] - fn neg(a: i128) -> i128 { - 0 - a - } -} - -impl I128Mul of Mul { - fn mul(lhs: i128, rhs: i128) -> i128 { - let (lhs_u127, lhs_neg) = match i128_diff(lhs, 0) { - Result::Ok(v) => (v, false), - Result::Err(v) => (~v + 1, true), - }; - let (rhs_u127, res_neg) = match i128_diff(rhs, 0) { - Result::Ok(v) => (v, lhs_neg), - Result::Err(v) => (~v + 1, !lhs_neg), - }; - let res_as_u128 = lhs_u127 * rhs_u127; - let res_as_felt252: felt252 = if res_neg { - -res_as_u128.into() - } else { - res_as_u128.into() - }; - res_as_felt252.try_into().expect('i128_mul Overflow') - } -} -impl I128MulEq of MulEq { - #[inline(always)] - fn mul_eq(ref self: i128, other: i128) { - self = Mul::mul(self, other); - } -} - -/// If `lhs` >= `rhs` returns `Ok(lhs - rhs)` else returns `Err(2**128 + lhs - rhs)`. -pub extern fn i128_diff(lhs: i128, rhs: i128) -> Result implicits(RangeCheck) nopanic; -impl I128PartialOrd of PartialOrd { - #[inline(always)] - fn le(lhs: i128, rhs: i128) -> bool { - i128_diff(rhs, lhs).into_is_ok() - } - #[inline(always)] - fn ge(lhs: i128, rhs: i128) -> bool { - i128_diff(lhs, rhs).into_is_ok() - } - #[inline(always)] - fn lt(lhs: i128, rhs: i128) -> bool { - i128_diff(lhs, rhs).into_is_err() - } - #[inline(always)] - fn gt(lhs: i128, rhs: i128) -> bool { - i128_diff(rhs, lhs).into_is_err() - } -} - -// Zeroable impls -pub(crate) impl U8Zeroable = core::zeroable::zero_based::ZeroableImpl; -pub(crate) impl U16Zeroable = core::zeroable::zero_based::ZeroableImpl; -pub(crate) impl U32Zeroable = core::zeroable::zero_based::ZeroableImpl; -pub(crate) impl U64Zeroable = core::zeroable::zero_based::ZeroableImpl; -pub(crate) impl U128Zeroable = core::zeroable::zero_based::ZeroableImpl; -pub(crate) impl U256Zeroable = core::zeroable::zero_based::ZeroableImpl; - -impl I128BitSize of core::num::traits::BitSize { - fn bits() -> usize { - 128 - } -} - -// Zero trait implementations -impl U8Zero of core::num::traits::Zero { - fn zero() -> u8 { - 0 - } - #[inline(always)] - fn is_zero(self: @u8) -> bool { - *self == U8Zero::zero() - } - #[inline(always)] - fn is_non_zero(self: @u8) -> bool { - !self.is_zero() - } -} - -impl U16Zero of core::num::traits::Zero { - fn zero() -> u16 { - 0 - } - #[inline(always)] - fn is_zero(self: @u16) -> bool { - *self == U16Zero::zero() - } - #[inline(always)] - fn is_non_zero(self: @u16) -> bool { - !self.is_zero() - } -} - -impl U32Zero of core::num::traits::Zero { - fn zero() -> u32 { - 0 - } - #[inline(always)] - fn is_zero(self: @u32) -> bool { - *self == U32Zero::zero() - } - #[inline(always)] - fn is_non_zero(self: @u32) -> bool { - !self.is_zero() - } -} - -impl U64Zero of core::num::traits::Zero { - fn zero() -> u64 { - 0 - } - #[inline(always)] - fn is_zero(self: @u64) -> bool { - *self == U64Zero::zero() - } - #[inline(always)] - fn is_non_zero(self: @u64) -> bool { - !self.is_zero() - } -} - -impl U128Zero of core::num::traits::Zero { - fn zero() -> u128 { - 0 - } - #[inline(always)] - fn is_zero(self: @u128) -> bool { - *self == U128Zero::zero() - } - #[inline(always)] - fn is_non_zero(self: @u128) -> bool { - !self.is_zero() - } -} - -impl U256Zero of core::num::traits::Zero { - fn zero() -> u256 { - 0 - } - #[inline(always)] - fn is_zero(self: @u256) -> bool { - *self == U256Zero::zero() - } - #[inline(always)] - fn is_non_zero(self: @u256) -> bool { - !self.is_zero() - } -} - -impl I8Zero of core::num::traits::Zero { - fn zero() -> i8 { - 0 - } - #[inline(always)] - fn is_zero(self: @i8) -> bool { - *self == I8Zero::zero() - } - #[inline(always)] - fn is_non_zero(self: @i8) -> bool { - !self.is_zero() - } -} - -impl I16Zero of core::num::traits::Zero { - fn zero() -> i16 { - 0 - } - #[inline(always)] - fn is_zero(self: @i16) -> bool { - *self == I16Zero::zero() - } - #[inline(always)] - fn is_non_zero(self: @i16) -> bool { - !self.is_zero() - } -} - -impl I32Zero of core::num::traits::Zero { - fn zero() -> i32 { - 0 - } - #[inline(always)] - fn is_zero(self: @i32) -> bool { - *self == I32Zero::zero() - } - #[inline(always)] - fn is_non_zero(self: @i32) -> bool { - !self.is_zero() - } -} - -impl I64Zero of core::num::traits::Zero { - fn zero() -> i64 { - 0 - } - #[inline(always)] - fn is_zero(self: @i64) -> bool { - *self == I64Zero::zero() - } - #[inline(always)] - fn is_non_zero(self: @i64) -> bool { - !self.is_zero() - } -} - -impl I128Zero of core::num::traits::Zero { - fn zero() -> i128 { - 0 - } - #[inline(always)] - fn is_zero(self: @i128) -> bool { - *self == I128Zero::zero() - } - #[inline(always)] - fn is_non_zero(self: @i128) -> bool { - !self.is_zero() - } -} - - -// One trait implementations -impl U8One of core::num::traits::One { - fn one() -> u8 { - 1 - } - #[inline(always)] - fn is_one(self: @u8) -> bool { - *self == U8One::one() - } - #[inline(always)] - fn is_non_one(self: @u8) -> bool { - !self.is_one() - } -} - -impl U16One of core::num::traits::One { - fn one() -> u16 { - 1 - } - #[inline(always)] - fn is_one(self: @u16) -> bool { - *self == U16One::one() - } - #[inline(always)] - fn is_non_one(self: @u16) -> bool { - !self.is_one() - } -} - -impl U32One of core::num::traits::One { - fn one() -> u32 { - 1 - } - #[inline(always)] - fn is_one(self: @u32) -> bool { - *self == U32One::one() - } - #[inline(always)] - fn is_non_one(self: @u32) -> bool { - !self.is_one() - } -} - -impl U64One of core::num::traits::One { - fn one() -> u64 { - 1 - } - #[inline(always)] - fn is_one(self: @u64) -> bool { - *self == U64One::one() - } - #[inline(always)] - fn is_non_one(self: @u64) -> bool { - !self.is_one() - } -} - -impl U128One of core::num::traits::One { - fn one() -> u128 { - 1 - } - #[inline(always)] - fn is_one(self: @u128) -> bool { - *self == U128One::one() - } - #[inline(always)] - fn is_non_one(self: @u128) -> bool { - !self.is_one() - } -} - -impl U256One of core::num::traits::One { - fn one() -> u256 { - 1 - } - #[inline(always)] - fn is_one(self: @u256) -> bool { - *self == U256One::one() - } - #[inline(always)] - fn is_non_one(self: @u256) -> bool { - !self.is_one() - } -} - -impl I8One of core::num::traits::One { - fn one() -> i8 { - 1 - } - - #[inline(always)] - fn is_one(self: @i8) -> bool { - *self == I8One::one() - } - - #[inline(always)] - fn is_non_one(self: @i8) -> bool { - !self.is_one() - } -} - -impl I16One of core::num::traits::One { - fn one() -> i16 { - 1 - } - - #[inline(always)] - fn is_one(self: @i16) -> bool { - *self == I16One::one() - } - - #[inline(always)] - fn is_non_one(self: @i16) -> bool { - !self.is_one() - } -} - -impl I32One of core::num::traits::One { - fn one() -> i32 { - 1 - } - - #[inline(always)] - fn is_one(self: @i32) -> bool { - *self == I32One::one() - } - - #[inline(always)] - fn is_non_one(self: @i32) -> bool { - !self.is_one() - } -} - -impl I64One of core::num::traits::One { - fn one() -> i64 { - 1 - } - - #[inline(always)] - fn is_one(self: @i64) -> bool { - *self == I64One::one() - } - - #[inline(always)] - fn is_non_one(self: @i64) -> bool { - !self.is_one() - } -} - -impl I128One of core::num::traits::One { - fn one() -> i128 { - 1 - } - - #[inline(always)] - fn is_one(self: @i128) -> bool { - *self == I128One::one() - } - - #[inline(always)] - fn is_non_one(self: @i128) -> bool { - !self.is_one() - } -} - -// OverflowingAdd implementations -impl U8OverflowingAdd of core::num::traits::OverflowingAdd { - fn overflowing_add(self: u8, v: u8) -> (u8, bool) { - match u8_overflowing_add(self, v) { - Result::Ok(x) => (x, false), - Result::Err(x) => (x, true) - } - } -} - -impl U16OverflowingAdd of core::num::traits::OverflowingAdd { - fn overflowing_add(self: u16, v: u16) -> (u16, bool) { - match u16_overflowing_add(self, v) { - Result::Ok(x) => (x, false), - Result::Err(x) => (x, true) - } - } -} - -impl U32OverflowingAdd of core::num::traits::OverflowingAdd { - fn overflowing_add(self: u32, v: u32) -> (u32, bool) { - match u32_overflowing_add(self, v) { - Result::Ok(x) => (x, false), - Result::Err(x) => (x, true) - } - } -} - -impl U64OverflowingAdd of core::num::traits::OverflowingAdd { - fn overflowing_add(self: u64, v: u64) -> (u64, bool) { - match u64_overflowing_add(self, v) { - Result::Ok(x) => (x, false), - Result::Err(x) => (x, true) - } - } -} - -impl U128OverflowingAdd of core::num::traits::OverflowingAdd { - fn overflowing_add(self: u128, v: u128) -> (u128, bool) { - match u128_overflowing_add(self, v) { - Result::Ok(x) => (x, false), - Result::Err(x) => (x, true) - } - } -} - -impl U256OverflowingAdd of core::num::traits::OverflowingAdd { - fn overflowing_add(self: u256, v: u256) -> (u256, bool) { - u256_overflowing_add(self, v) - } -} - -impl I8OverflowingAdd of core::num::traits::OverflowingAdd { - fn overflowing_add(self: i8, v: i8) -> (i8, bool) { - match i8_overflowing_add_impl(self, v) { - SignedIntegerResult::InRange(x) => (x, false), - SignedIntegerResult::Underflow(x) => (x, true), - SignedIntegerResult::Overflow(x) => (x, true), - } - } -} - -impl I16OverflowingAdd of core::num::traits::OverflowingAdd { - fn overflowing_add(self: i16, v: i16) -> (i16, bool) { - match i16_overflowing_add_impl(self, v) { - SignedIntegerResult::InRange(x) => (x, false), - SignedIntegerResult::Underflow(x) => (x, true), - SignedIntegerResult::Overflow(x) => (x, true), - } - } -} - -impl I32OverflowingAdd of core::num::traits::OverflowingAdd { - fn overflowing_add(self: i32, v: i32) -> (i32, bool) { - match i32_overflowing_add_impl(self, v) { - SignedIntegerResult::InRange(x) => (x, false), - SignedIntegerResult::Underflow(x) => (x, true), - SignedIntegerResult::Overflow(x) => (x, true), - } - } -} - -impl I64OverflowingAdd of core::num::traits::OverflowingAdd { - fn overflowing_add(self: i64, v: i64) -> (i64, bool) { - match i64_overflowing_add_impl(self, v) { - SignedIntegerResult::InRange(x) => (x, false), - SignedIntegerResult::Underflow(x) => (x, true), - SignedIntegerResult::Overflow(x) => (x, true), - } - } -} - -impl I128OverflowingAdd of core::num::traits::OverflowingAdd { - fn overflowing_add(self: i128, v: i128) -> (i128, bool) { - match i128_overflowing_add_impl(self, v) { - SignedIntegerResult::InRange(x) => (x, false), - SignedIntegerResult::Underflow(x) => (x, true), - SignedIntegerResult::Overflow(x) => (x, true), - } - } -} - -// OverflowingSub implementations -impl U8OverflowingSub of core::num::traits::OverflowingSub { - fn overflowing_sub(self: u8, v: u8) -> (u8, bool) { - match u8_overflowing_sub(self, v) { - Result::Ok(x) => (x, false), - Result::Err(x) => (x, true) - } - } -} - -impl U16OverflowingSub of core::num::traits::OverflowingSub { - fn overflowing_sub(self: u16, v: u16) -> (u16, bool) { - match u16_overflowing_sub(self, v) { - Result::Ok(x) => (x, false), - Result::Err(x) => (x, true) - } - } -} - -impl U32OverflowingSub of core::num::traits::OverflowingSub { - fn overflowing_sub(self: u32, v: u32) -> (u32, bool) { - match u32_overflowing_sub(self, v) { - Result::Ok(x) => (x, false), - Result::Err(x) => (x, true) - } - } -} - -impl U64OverflowingSub of core::num::traits::OverflowingSub { - fn overflowing_sub(self: u64, v: u64) -> (u64, bool) { - match u64_overflowing_sub(self, v) { - Result::Ok(x) => (x, false), - Result::Err(x) => (x, true) - } - } -} - -impl U128OverflowingSub of core::num::traits::OverflowingSub { - fn overflowing_sub(self: u128, v: u128) -> (u128, bool) { - match u128_overflowing_sub(self, v) { - Result::Ok(x) => (x, false), - Result::Err(x) => (x, true) - } - } -} - -impl U256OverflowingSub of core::num::traits::OverflowingSub { - fn overflowing_sub(self: u256, v: u256) -> (u256, bool) { - u256_overflow_sub(self, v) - } -} - -impl I8OverflowingSub of core::num::traits::OverflowingSub { - fn overflowing_sub(self: i8, v: i8) -> (i8, bool) { - match i8_overflowing_sub_impl(self, v) { - SignedIntegerResult::InRange(x) => (x, false), - SignedIntegerResult::Underflow(x) => (x, true), - SignedIntegerResult::Overflow(x) => (x, true), - } - } -} - -impl I16OverflowingSub of core::num::traits::OverflowingSub { - fn overflowing_sub(self: i16, v: i16) -> (i16, bool) { - match i16_overflowing_sub_impl(self, v) { - SignedIntegerResult::InRange(x) => (x, false), - SignedIntegerResult::Underflow(x) => (x, true), - SignedIntegerResult::Overflow(x) => (x, true), - } - } -} - -impl I32OverflowingSub of core::num::traits::OverflowingSub { - fn overflowing_sub(self: i32, v: i32) -> (i32, bool) { - match i32_overflowing_sub_impl(self, v) { - SignedIntegerResult::InRange(x) => (x, false), - SignedIntegerResult::Underflow(x) => (x, true), - SignedIntegerResult::Overflow(x) => (x, true), - } - } -} - -impl I64OverflowingSub of core::num::traits::OverflowingSub { - fn overflowing_sub(self: i64, v: i64) -> (i64, bool) { - match i64_overflowing_sub_impl(self, v) { - SignedIntegerResult::InRange(x) => (x, false), - SignedIntegerResult::Underflow(x) => (x, true), - SignedIntegerResult::Overflow(x) => (x, true), - } - } -} - -impl I128OverflowingSub of core::num::traits::OverflowingSub { - fn overflowing_sub(self: i128, v: i128) -> (i128, bool) { - match i128_overflowing_sub_impl(self, v) { - SignedIntegerResult::InRange(x) => (x, false), - SignedIntegerResult::Underflow(x) => (x, true), - SignedIntegerResult::Overflow(x) => (x, true), - } - } -} - -// OverflowingMul implementations -impl U8OverflowingMul of core::num::traits::OverflowingMul { - fn overflowing_mul(self: u8, v: u8) -> (u8, bool) { - let wide_result = u8_wide_mul(self, v); - let MASK: u16 = BoundedInt::::max().into(); - let (v_low, _, v_with_low_masked) = u16_bitwise(wide_result, MASK); - (v_low.try_into().unwrap(), v_with_low_masked != MASK) - } -} - -impl U16OverflowingMul of core::num::traits::OverflowingMul { - fn overflowing_mul(self: u16, v: u16) -> (u16, bool) { - let wide_result = u16_wide_mul(self, v); - let MASK: u32 = BoundedInt::::max().into(); - let (v_low, _, v_with_low_masked) = u32_bitwise(wide_result, MASK); - (v_low.try_into().unwrap(), v_with_low_masked != MASK) - } -} - -impl U32OverflowingMul of core::num::traits::OverflowingMul { - fn overflowing_mul(self: u32, v: u32) -> (u32, bool) { - let wide_result = u32_wide_mul(self, v); - let MASK: u64 = BoundedInt::::max().into(); - let (v_low, _, v_with_low_masked) = u64_bitwise(wide_result, MASK); - (v_low.try_into().unwrap(), v_with_low_masked != MASK) - } -} - -impl U64OverflowingMul of core::num::traits::OverflowingMul { - fn overflowing_mul(self: u64, v: u64) -> (u64, bool) { - let wide_result = u64_wide_mul(self, v); - let MASK: u128 = BoundedInt::::max().into(); - let (v_low, _, v_with_low_masked) = bitwise(wide_result, MASK); - (v_low.try_into().unwrap(), v_with_low_masked != MASK) - } -} - -impl U128OverflowingMul of core::num::traits::OverflowingMul { - fn overflowing_mul(self: u128, v: u128) -> (u128, bool) { - u128_overflowing_mul(self, v) - } -} - -impl U256OverflowingMul of core::num::traits::OverflowingMul { - fn overflowing_mul(self: u256, v: u256) -> (u256, bool) { - u256_overflow_mul(self, v) - } -} - -/// WrappingAdd implementations -impl U8WrappingAdd = core::num::traits::ops::wrapping::overflow_based::TWrappingAdd; -impl U16WrappingAdd = core::num::traits::ops::wrapping::overflow_based::TWrappingAdd; -impl U32WrappingAdd = core::num::traits::ops::wrapping::overflow_based::TWrappingAdd; -impl U64WrappingAdd = core::num::traits::ops::wrapping::overflow_based::TWrappingAdd; -impl U128WrappingAdd = core::num::traits::ops::wrapping::overflow_based::TWrappingAdd; -impl U256WrappingAdd = core::num::traits::ops::wrapping::overflow_based::TWrappingAdd; -impl I8WrappingAdd = core::num::traits::ops::wrapping::overflow_based::TWrappingAdd; -impl I16WrappingAdd = core::num::traits::ops::wrapping::overflow_based::TWrappingAdd; -impl I32WrappingAdd = core::num::traits::ops::wrapping::overflow_based::TWrappingAdd; -impl I64WrappingAdd = core::num::traits::ops::wrapping::overflow_based::TWrappingAdd; -impl I128WrappingAdd = core::num::traits::ops::wrapping::overflow_based::TWrappingAdd; - -/// WrappingSub implementations -impl U8WrappingSub = core::num::traits::ops::wrapping::overflow_based::TWrappingSub; -impl U16WrappingSub = core::num::traits::ops::wrapping::overflow_based::TWrappingSub; -impl U32WrappingSub = core::num::traits::ops::wrapping::overflow_based::TWrappingSub; -impl U64WrappingSub = core::num::traits::ops::wrapping::overflow_based::TWrappingSub; -impl U128WrappingSub = core::num::traits::ops::wrapping::overflow_based::TWrappingSub; -impl U256WrappingSub = core::num::traits::ops::wrapping::overflow_based::TWrappingSub; -impl I8WrappingSub = core::num::traits::ops::wrapping::overflow_based::TWrappingSub; -impl I16WrappingSub = core::num::traits::ops::wrapping::overflow_based::TWrappingSub; -impl I32WrappingSub = core::num::traits::ops::wrapping::overflow_based::TWrappingSub; -impl I64WrappingSub = core::num::traits::ops::wrapping::overflow_based::TWrappingSub; -impl I128WrappingSub = core::num::traits::ops::wrapping::overflow_based::TWrappingSub; - -/// WrappingMul implementations -impl U8WrappingMul = core::num::traits::ops::wrapping::overflow_based::TWrappingMul; -impl U16WrappingMul = core::num::traits::ops::wrapping::overflow_based::TWrappingMul; -impl U32WrappingMul = core::num::traits::ops::wrapping::overflow_based::TWrappingMul; -impl U64WrappingMul = core::num::traits::ops::wrapping::overflow_based::TWrappingMul; -impl U128WrappingMul = core::num::traits::ops::wrapping::overflow_based::TWrappingMul; -impl U256WrappingMul = core::num::traits::ops::wrapping::overflow_based::TWrappingMul; diff --git a/corelib/src/internal.cairo b/corelib/src/internal.cairo deleted file mode 100644 index 8513e7cdd..000000000 --- a/corelib/src/internal.cairo +++ /dev/null @@ -1,11 +0,0 @@ -pub extern fn revoke_ap_tracking() implicits() nopanic; - -/// Function to enforce that `Implicit` is used by a function calling it. -/// Note: This extern function is not mapped to a Sierra function, and all usages of it are removed -/// during compilation. -pub extern fn require_implicit() implicits(Implicit) nopanic; - -extern type index_enum_type; - -extern type BoundedInt; - diff --git a/corelib/src/keccak.cairo b/corelib/src/keccak.cairo deleted file mode 100644 index 3bad2138c..000000000 --- a/corelib/src/keccak.cairo +++ /dev/null @@ -1,150 +0,0 @@ -use core::array::{Span, ArrayTrait, SpanTrait}; -use core::traits::TryInto; -use core::option::OptionTrait; -use core::starknet::SyscallResultTrait; - -const KECCAK_FULL_RATE_IN_BYTES: usize = 136; -const KECCAK_FULL_RATE_IN_U64S: usize = 17; -const BYTES_IN_U64_WORD: usize = 8; - - -fn u128_to_u64(input: u128) -> u64 { - input.try_into().unwrap() -} - -fn u128_split(input: u128) -> (u64, u64) { - let (high, low) = core::integer::u128_safe_divmod( - input, 0x10000000000000000_u128.try_into().unwrap() - ); - - (u128_to_u64(high), u128_to_u64(low)) -} - -fn keccak_add_u256_le(ref keccak_input: Array::, v: u256) { - let (high, low) = u128_split(v.low); - keccak_input.append(low); - keccak_input.append(high); - let (high, low) = u128_split(v.high); - keccak_input.append(low); - keccak_input.append(high); -} - - -// Computes the keccak256 of multiple u256 values. -// The input values are interpreted as little-endian. -// The 32-byte result is represented as a little-endian u256. -pub fn keccak_u256s_le_inputs(mut input: Span) -> u256 { - let mut keccak_input: Array:: = Default::default(); - - loop { - match input.pop_front() { - Option::Some(v) => { keccak_add_u256_le(ref keccak_input, *v); }, - Option::None => { break (); }, - }; - }; - - add_padding(ref keccak_input, 0, 0); - starknet::syscalls::keccak_syscall(keccak_input.span()).unwrap_syscall() -} - -fn keccak_add_u256_be(ref keccak_input: Array::, v: u256) { - let (high, low) = u128_split(core::integer::u128_byte_reverse(v.high)); - keccak_input.append(low); - keccak_input.append(high); - let (high, low) = u128_split(core::integer::u128_byte_reverse(v.low)); - keccak_input.append(low); - keccak_input.append(high); -} - -// Computes the keccak256 of multiple u256 values. -// The input values are interpreted as big-endian. -// The 32-byte result is represented as a little-endian u256. -pub fn keccak_u256s_be_inputs(mut input: Span) -> u256 { - let mut keccak_input: Array:: = Default::default(); - - loop { - match input.pop_front() { - Option::Some(v) => { keccak_add_u256_be(ref keccak_input, *v); }, - Option::None => { break (); }, - }; - }; - - add_padding(ref keccak_input, 0, 0); - starknet::syscalls::keccak_syscall(keccak_input.span()).unwrap_syscall() -} - -// Computes the keccak of `input` + `last_input_num_bytes` LSB bytes of `last_input_word`. -// To use this function, split the input into words of 64 bits (little endian). -// For example, to compute keccak('Hello world!'), use: -// inputs = [8031924123371070792, 560229490] -// where: -// 8031924123371070792 == int.from_bytes(b'Hello wo', 'little') -// 560229490 == int.from_bytes(b'rld!', 'little') -// -// Returns the hash as a little endian u256. -pub fn cairo_keccak( - ref input: Array, last_input_word: u64, last_input_num_bytes: usize -) -> u256 { - add_padding(ref input, last_input_word, last_input_num_bytes); - starknet::syscalls::keccak_syscall(input.span()).unwrap_syscall() -} - -// The padding in keccak256 is "1 0* 1". -// `last_input_num_bytes` (0-7) is the number of bytes in the last u64 input - `last_input_word`. -fn add_padding(ref input: Array, last_input_word: u64, last_input_num_bytes: usize) { - let words_divisor = KECCAK_FULL_RATE_IN_U64S.try_into().unwrap(); - // `last_block_num_full_words` is in range [0, KECCAK_FULL_RATE_IN_U64S - 1] - let (_, last_block_num_full_words) = core::integer::u32_safe_divmod(input.len(), words_divisor); - - // The first word to append would be of the form - // 0x1<`last_input_num_bytes` LSB bytes of `last_input_word`>. - // For example, for `last_input_num_bytes == 4`: - // 0x1000000 + (last_input_word & 0xffffff) - let first_word_to_append = if last_input_num_bytes == 0 { - // This case is handled separately to avoid unnecessary computations. - 1 - } else { - let first_padding_byte_part = if last_input_num_bytes == 1 { - 0x100 - } else if last_input_num_bytes == 2 { - 0x10000 - } else if last_input_num_bytes == 3 { - 0x1000000 - } else if last_input_num_bytes == 4 { - 0x100000000 - } else if last_input_num_bytes == 5 { - 0x10000000000 - } else if last_input_num_bytes == 6 { - 0x1000000000000 - } else if last_input_num_bytes == 7 { - 0x100000000000000 - } else { - core::panic_with_felt252('Keccak last input word >7b') - }; - let (_, r) = core::integer::u64_safe_divmod( - last_input_word, first_padding_byte_part.try_into().unwrap() - ); - first_padding_byte_part + r - }; - - if last_block_num_full_words == KECCAK_FULL_RATE_IN_U64S - 1 { - input.append(0x8000000000000000 + first_word_to_append); - return; - } - - // last_block_num_full_words < KECCAK_FULL_RATE_IN_U64S - 1 - input.append(first_word_to_append); - finalize_padding(ref input, KECCAK_FULL_RATE_IN_U64S - 1 - last_block_num_full_words); -} - -// Finalize the padding by appending "0* 1". -fn finalize_padding(ref input: Array, num_padding_words: u32) { - if (num_padding_words == 1) { - input.append(0x8000000000000000); - return; - } - - input.append(0); - finalize_padding(ref input, num_padding_words - 1); -} - diff --git a/corelib/src/lib.cairo b/corelib/src/lib.cairo deleted file mode 100644 index 777f45d2a..000000000 --- a/corelib/src/lib.cairo +++ /dev/null @@ -1,369 +0,0 @@ -pub mod traits; -use traits::{ - Add, AddEq, BitAnd, BitNot, BitOr, BitXor, Copy, Div, DivEq, DivRem, Drop, Mul, MulEq, - PartialEq, PartialOrd, Rem, RemEq, Sub, SubEq, TupleSize0Copy, TupleSize0Drop, Not, Neg, Into, - TryInto, Index, IndexView, Destruct, Default, Felt252DictValue, PanicDestruct -}; -use serde::Serde; - -pub type usize = u32; - -#[derive(Copy, Drop, Default)] -pub enum bool { - #[default] - False, - True, -} - -impl BoolSerde of Serde { - fn serialize(self: @bool, ref output: Array) { - if *self { - 1_felt252 - } else { - 0_felt252 - }.serialize(ref output); - } - fn deserialize(ref serialized: Span) -> Option { - Option::Some(*serialized.pop_front()? != 0) - } -} - -extern fn bool_and_impl(lhs: bool, rhs: bool) -> (bool,) implicits() nopanic; -impl BoolBitAnd of BitAnd { - #[inline(always)] - fn bitand(lhs: bool, rhs: bool) -> bool { - let (r,) = bool_and_impl(lhs, rhs); - r - } -} - -extern fn bool_or_impl(lhs: bool, rhs: bool) -> (bool,) implicits() nopanic; -impl BoolBitOr of BitOr { - #[inline(always)] - fn bitor(lhs: bool, rhs: bool) -> bool { - let (r,) = bool_or_impl(lhs, rhs); - r - } -} - -extern fn bool_not_impl(a: bool) -> (bool,) implicits() nopanic; -#[inline(always)] -impl BoolNot of Not { - #[inline(always)] - fn not(a: bool) -> bool implicits() nopanic { - let (r,) = bool_not_impl(a); - r - } -} - -extern fn bool_xor_impl(lhs: bool, rhs: bool) -> (bool,) implicits() nopanic; -impl BoolBitXor of BitXor { - #[inline(always)] - fn bitxor(lhs: bool, rhs: bool) -> bool { - let (r,) = bool_xor_impl(lhs, rhs); - r - } -} - -impl BoolPartialEq of PartialEq { - #[inline(always)] - fn eq(lhs: @bool, rhs: @bool) -> bool { - match lhs { - false => !*rhs, - true => *rhs, - } - } - #[inline(always)] - fn ne(lhs: @bool, rhs: @bool) -> bool { - match lhs { - false => *rhs, - true => !*rhs, - } - } -} - -/// Default values for felt252_dict values. -impl BoolFelt252DictValue of Felt252DictValue { - #[inline(always)] - fn zero_default() -> bool nopanic { - false - } -} - -extern fn bool_to_felt252(a: bool) -> felt252 implicits() nopanic; -impl BoolIntoFelt252 of Into { - #[inline(always)] - fn into(self: bool) -> felt252 implicits() nopanic { - bool_to_felt252(self) - } -} -pub mod boolean; - -// General purpose implicits. -pub extern type RangeCheck; -pub extern type SegmentArena; - -// felt252. -mod felt_252; -use felt_252::{Felt252One, Felt252Zero}; - -#[derive(Copy, Drop)] -pub extern type felt252; -extern fn felt252_const() -> felt252 nopanic; - -impl Felt252Serde of Serde { - fn serialize(self: @felt252, ref output: Array) { - output.append(*self); - } - fn deserialize(ref serialized: Span) -> Option { - let mut snapshot = serialized.snapshot; - match core::array::array_snapshot_pop_front(ref snapshot) { - Option::Some(x) => { - serialized = Span { snapshot }; - Option::Some(*x.unbox()) - }, - Option::None => { - serialized = Span { snapshot }; - Option::None - }, - } - } -} - -impl Felt252Add of Add { - #[inline(always)] - fn add(lhs: felt252, rhs: felt252) -> felt252 { - felt252_add(lhs, rhs) - } -} -impl Felt252AddEq of AddEq { - #[inline(always)] - fn add_eq(ref self: felt252, other: felt252) { - self = Add::add(self, other); - } -} - -extern fn felt252_add(lhs: felt252, rhs: felt252) -> felt252 nopanic; -impl Felt252Sub of Sub { - #[inline(always)] - fn sub(lhs: felt252, rhs: felt252) -> felt252 { - felt252_sub(lhs, rhs) - } -} -impl Felt252SubEq of SubEq { - #[inline(always)] - fn sub_eq(ref self: felt252, other: felt252) { - self = Sub::sub(self, other); - } -} - -extern fn felt252_sub(lhs: felt252, rhs: felt252) -> felt252 nopanic; -impl Felt252Mul of Mul { - #[inline(always)] - fn mul(lhs: felt252, rhs: felt252) -> felt252 { - felt252_mul(lhs, rhs) - } -} -impl Felt252MulEq of MulEq { - #[inline(always)] - fn mul_eq(ref self: felt252, other: felt252) { - self = Mul::mul(self, other); - } -} - -extern fn felt252_mul(lhs: felt252, rhs: felt252) -> felt252 nopanic; - -impl Felt252Neg of Neg { - #[inline(always)] - fn neg(a: felt252) -> felt252 { - a * -1 - } -} - -pub extern fn felt252_div(lhs: felt252, rhs: NonZero) -> felt252 nopanic; - -impl Felt252PartialEq of PartialEq { - #[inline(always)] - fn eq(lhs: @felt252, rhs: @felt252) -> bool { - match *lhs - *rhs { - 0 => true, - _ => false, - } - } - #[inline(always)] - fn ne(lhs: @felt252, rhs: @felt252) -> bool { - !(*lhs == *rhs) - } -} - -extern fn felt252_is_zero(lhs: felt252) -> zeroable::IsZeroResult nopanic; - -impl Felt252TryIntoNonZero of TryInto> { - fn try_into(self: felt252) -> Option> { - match felt252_is_zero(self) { - zeroable::IsZeroResult::Zero => Option::None, - zeroable::IsZeroResult::NonZero(x) => Option::Some(x), - } - } -} - -impl Felt252Default of Default { - #[inline(always)] - fn default() -> felt252 nopanic { - 0 - } -} - -impl Felt252Felt252DictValue of Felt252DictValue { - #[inline(always)] - fn zero_default() -> felt252 nopanic { - 0 - } -} - -// TODO(spapini): Constraint using Copy and Drop traits. -extern fn dup(obj: T) -> (T, T) nopanic; -extern fn drop(obj: T) nopanic; - -// Boxes. -pub mod box; -use box::{Box, BoxTrait}; - -// Nullable -pub mod nullable; -use nullable::{Nullable, NullableTrait, match_nullable, null, nullable_from_box}; - -// Array. -pub mod array; -use array::{Array, ArrayTrait}; - -// Span. -use array::{Span, SpanTrait}; - -// Dictionary. -pub mod dict; -use dict::{ - Felt252Dict, SquashedFelt252Dict, felt252_dict_new, felt252_dict_squash, Felt252DictTrait -}; - -// Result. -pub mod result; -use result::{Result, ResultTrait}; - -// Option. -pub mod option; -use option::{Option, OptionTrait}; - -// Clone. -pub mod clone; -use clone::Clone; - -// EC. -pub mod ec; -use ec::{EcOp, EcPoint, EcState}; - -pub mod ecdsa; - -// Integer. -pub mod integer; -use integer::{ - i8, I8IntoFelt252, i16, I16IntoFelt252, i32, I32IntoFelt252, i64, I64IntoFelt252, i128, - I128IntoFelt252, NumericLiteral, u128, u128_sqrt, u128_is_zero, u8, u16, u32, u64, u256, - u256_sqrt, Felt252TryIntoU8, U8IntoFelt252, Felt252TryIntoU16, U16IntoFelt252, - Felt252TryIntoU32, U32IntoFelt252, Felt252TryIntoU64, U64IntoFelt252, Felt252TryIntoU128, - U128IntoFelt252, Felt252IntoU256, Bitwise -}; - -// Math. -pub mod math; - -// Num. -pub mod num; - -// Cmp. -pub mod cmp; - -// Gas. -pub mod gas; -use gas::{BuiltinCosts, GasBuiltin, get_builtin_costs}; - - -// Panics. -pub mod panics; -use panics::{panic, Panic, PanicResult}; - -pub enum never {} - -#[inline(always)] -pub fn panic_with_felt252(err_code: felt252) -> never { - panic(array![err_code]) -} - -#[inline(always)] -pub fn assert(cond: bool, err_code: felt252) { - if !cond { - panic_with_felt252(err_code) - } -} - -// Serialization and Deserialization. -pub mod serde; - -// Hash functions. -pub mod hash; - -pub mod keccak; - -// Pedersen -pub mod pedersen; -use pedersen::Pedersen; - -// Poseidon -pub mod poseidon; -use poseidon::Poseidon; - -// Debug. -pub mod debug; - -pub mod fmt; - -// Starknet -pub mod starknet; -use starknet::System; - -// Internals. -pub mod internal; - -// Zeroable. -pub mod zeroable; -use zeroable::{Zeroable, NonZero}; - -// bytes31. -pub mod bytes_31; -use bytes_31::{ - bytes31, bytes31_const, Bytes31IndexView, Bytes31IntoFelt252, Bytes31Trait, - Felt252TryIntoBytes31 -}; - -// BytesArray. -pub mod byte_array; -use byte_array::{ByteArray, ByteArrayIndexView, ByteArrayStringLiteral, ByteArrayTrait}; - -// String. -pub mod string; -use string::StringLiteral; - -// to_byte_array. -pub mod to_byte_array; - -#[cfg(test)] -mod test; - -// Module for testing only. -pub mod testing; - -// Metaprogramming. -pub mod metaprogramming; - -// Preludes. -mod prelude; diff --git a/corelib/src/math.cairo b/corelib/src/math.cairo deleted file mode 100644 index e1ea0825c..000000000 --- a/corelib/src/math.cairo +++ /dev/null @@ -1,160 +0,0 @@ -use core::zeroable::{IsZeroResult, NonZeroIntoImpl, Zeroable}; -use core::traits::{Into, TryInto}; -use core::option::OptionTrait; -use core::integer::{u256_wide_mul, u512_safe_div_rem_by_u256, U128MulGuarantee}; - -// TODO(yuval): use signed integers once supported. -// TODO(yuval): use a single impl of a trait with associated impls, once associated impls are -// supported. -/// Extended GCD: finds (g, s, t, sub_direction) such that -/// `g = gcd(a, b) = s * a - t * b` if `sub_direction` is true, or -/// `g = gcd(a, b) = t * b - s * a` if `sub_direction` is false. -/// `(s, -t)` or `(-s, t)` are the Bezout coefficients (according to `sub_direction`). -/// -/// Uses the Extended Euclidean algorithm. -pub fn egcd< - T, - +Copy, - +Drop, - +Add, - +Mul, - +DivRem, - +Zeroable, - +Oneable, - +TryInto>, ->( - a: NonZero, b: NonZero -) -> (T, T, T, bool) { - let (q, r) = DivRem::::div_rem(a.into(), b); - - if r.is_zero() { - return (b.into(), Zeroable::zero(), Oneable::one(), false); - } - - // `sign` (1 for true, -1 for false) is the sign of `g` in the current iteration. - // 0 is considered negative for this purpose. - let (g, s, t, sign) = egcd(b, r.try_into().unwrap()); - // We know that `a = q*b + r` and that `s*b - t*r = sign*g`. - // So `t*a - (s + q*t)*b = t*r - s*b = sign*g`. - // Thus we pick `new_s = t`, `new_t = s + q*t`, `new_sign = !sign`. - (g, t, s + q * t, !sign) -} - -// TODO(yuval): use signed integers once supported. -/// Returns the inverse of `a` modulo `n`, or None if `gcd(a, n) > 1`. -pub fn inv_mod< - T, - +Copy, - +Drop, - +Add, - +Sub, - +Mul, - +DivRem, - +Zeroable, - +Oneable, - +TryInto>, ->( - a: NonZero, n: NonZero -) -> Option { - if Oneable::::is_one(n.into()) { - return Option::Some(Zeroable::zero()); - } - let (g, s, _, sub_direction) = egcd(a, n); - if g.is_one() { - // `1 = g = gcd(a, n) = +-(s*a - t*n) => s*a = +-1 (mod n)`. - // The absolute values of Bezout coefficients are guaranteed to be `< n`. - // With n > 1 and gcd = 1, `s` can't be 0. - if sub_direction { - // `s` is the Bezout coefficient, `0 < s < n`. - Option::Some(s) - } else { - // `-s` is the Bezout coefficient. - // `-n < -s < 0 => 0 < n - s < n`, and `n - s = -s (mod n)`. - Option::Some(n.into() - s) - } - } else { - Option::None - } -} - -/// Returns `1 / b (mod n)`, or None if `b` is not invertible modulo `n`. -/// All `b`s will be considered not invertible for `n == 1`. -/// Additionally returns several `U128MulGuarantee`s that are required for validating the -/// calculation. -extern fn u256_guarantee_inv_mod_n( - b: u256, n: NonZero -) -> Result< - ( - NonZero, - U128MulGuarantee, - U128MulGuarantee, - U128MulGuarantee, - U128MulGuarantee, - U128MulGuarantee, - U128MulGuarantee, - U128MulGuarantee, - U128MulGuarantee - ), - (U128MulGuarantee, U128MulGuarantee) -> implicits(RangeCheck) nopanic; - -/// Returns the inverse of `a` modulo `n`, or None if `a` is not invertible modulo `n`. -/// All `b`s will be considered not invertible for `n == 1`. -#[inline(always)] -pub fn u256_inv_mod(a: u256, n: NonZero) -> Option> { - match u256_guarantee_inv_mod_n(a, n) { - Result::Ok((inv_a, _, _, _, _, _, _, _, _)) => Option::Some(inv_a), - Result::Err(_) => Option::None(()) - } -} - -/// Returns `a / b (mod n)`, or None if `b` is not invertible modulo `n`. -pub fn u256_div_mod_n(a: u256, b: u256, n: NonZero) -> Option { - Option::Some(u256_mul_mod_n(a, u256_inv_mod(b, n)?.into(), n)) -} - -/// Returns `a * b (mod n)`. -pub fn u256_mul_mod_n(a: u256, b: u256, n: NonZero) -> u256 { - let (_, r) = u512_safe_div_rem_by_u256(u256_wide_mul(a, b), n); - r -} - -// === Oneable === - -trait Oneable { - /// Returns the multiplicative identity element of Self, 1. - #[must_use] - fn one() -> T; - /// Returns whether self is equal to 1, the multiplicative identity element. - #[must_use] - fn is_one(self: T) -> bool; - /// Returns whether self is not equal to 1, the multiplicative identity element. - #[must_use] - fn is_non_one(self: T) -> bool; -} - -pub(crate) mod one_based { - pub(crate) impl OneableImpl< - T, impl OneImpl: core::num::traits::One, +Drop, +Copy - > of super::Oneable { - fn one() -> T { - OneImpl::one() - } - #[inline(always)] - fn is_one(self: T) -> bool { - OneImpl::is_one(@self) - } - #[inline(always)] - fn is_non_one(self: T) -> bool { - OneImpl::is_non_one(@self) - } - } -} - -// Oneable impls -impl U8Oneable = math::one_based::OneableImpl; -impl U16Oneable = math::one_based::OneableImpl; -impl U32Oneable = math::one_based::OneableImpl; -impl U64Oneable = math::one_based::OneableImpl; -impl U128Oneable = math::one_based::OneableImpl; -impl U256Oneable = math::one_based::OneableImpl; diff --git a/corelib/src/metaprogramming.cairo b/corelib/src/metaprogramming.cairo deleted file mode 100644 index 87ed62e9d..000000000 --- a/corelib/src/metaprogramming.cairo +++ /dev/null @@ -1,5 +0,0 @@ -/// A trait that can be used to disable implementations based on the types of the generic args. -/// Assumes that `TypeEqualImpl` is the only implementation of this trait. -pub trait TypeEqual {} - -impl TypeEqualImpl of TypeEqual; diff --git a/corelib/src/nullable.cairo b/corelib/src/nullable.cairo deleted file mode 100644 index 5f2c37ba5..000000000 --- a/corelib/src/nullable.cairo +++ /dev/null @@ -1,74 +0,0 @@ -use core::box::BoxTrait; -use core::traits::Default; -use core::traits::Felt252DictValue; - -#[derive(Copy, Drop)] -pub extern type Nullable; - -pub enum FromNullableResult { - Null, - NotNull: Box, -} - -pub extern fn null() -> Nullable nopanic; -pub(crate) extern fn nullable_from_box(value: Box) -> Nullable nopanic; -pub extern fn match_nullable(value: Nullable) -> FromNullableResult nopanic; -extern fn nullable_forward_snapshot(value: @Nullable) -> Nullable<@T> nopanic; - -#[generate_trait] -pub impl NullableImpl of NullableTrait { - fn deref(self: Nullable) -> T { - match match_nullable(self) { - FromNullableResult::Null => core::panic_with_felt252('Attempted to deref null value'), - FromNullableResult::NotNull(value) => value.unbox(), - } - } - fn deref_or<+Drop>(self: Nullable, default: T) -> T { - match match_nullable(self) { - FromNullableResult::Null => default, - FromNullableResult::NotNull(value) => value.unbox(), - } - } - #[must_use] - fn new(value: T) -> Nullable { - nullable_from_box(BoxTrait::new(value)) - } - #[must_use] - fn is_null(self: @Nullable) -> bool { - match match_nullable(self.as_snapshot()) { - FromNullableResult::Null => true, - FromNullableResult::NotNull(_) => false, - } - } - fn as_snapshot(self: @Nullable) -> Nullable<@T> nopanic { - nullable_forward_snapshot(self) - } -} - -impl NullableDefault of Default> { - #[inline(always)] - #[must_use] - fn default() -> Nullable nopanic { - null() - } -} - -impl NullableFelt252DictValue of Felt252DictValue> { - #[inline(always)] - #[must_use] - fn zero_default() -> Nullable nopanic { - null() - } -} - -impl NullableDebug> of core::fmt::Debug> { - fn fmt(self: @Nullable, ref f: core::fmt::Formatter) -> Result<(), core::fmt::Error> { - match match_nullable(self.as_snapshot()) { - FromNullableResult::Null => write!(f, "null"), - FromNullableResult::NotNull(value) => { - write!(f, "&")?; - TDebug::fmt(value.unbox(), ref f) - }, - } - } -} diff --git a/corelib/src/num.cairo b/corelib/src/num.cairo deleted file mode 100644 index f6ac8fc7b..000000000 --- a/corelib/src/num.cairo +++ /dev/null @@ -1 +0,0 @@ -pub mod traits; diff --git a/corelib/src/num/traits.cairo b/corelib/src/num/traits.cairo deleted file mode 100644 index 1dcb2ed03..000000000 --- a/corelib/src/num/traits.cairo +++ /dev/null @@ -1,12 +0,0 @@ -pub mod zero; -pub use zero::Zero; - -pub mod one; -pub use one::One; - -pub mod bit_size; -pub use bit_size::BitSize; - -pub mod ops; -pub use ops::overflowing::{OverflowingAdd, OverflowingSub, OverflowingMul}; -pub use ops::wrapping::{WrappingAdd, WrappingSub, WrappingMul}; diff --git a/corelib/src/num/traits/bit_size.cairo b/corelib/src/num/traits/bit_size.cairo deleted file mode 100644 index 76d50a40b..000000000 --- a/corelib/src/num/traits/bit_size.cairo +++ /dev/null @@ -1,6 +0,0 @@ -/// Trait used to retrieve the size in bits of a type. -pub trait BitSize { - /// Returns the size in bits of T as usize. - #[must_use] - fn bits() -> usize; -} diff --git a/corelib/src/num/traits/one.cairo b/corelib/src/num/traits/one.cairo deleted file mode 100644 index 34ff7a0b2..000000000 --- a/corelib/src/num/traits/one.cairo +++ /dev/null @@ -1,9 +0,0 @@ -/// Defines a multiplicative identity element for `T`. -pub trait One { - /// Returns the multiplicative identity element of `T`, `1`. - fn one() -> T; - /// Returns `true` if `self` is equal to the multiplicative identity. - fn is_one(self: @T) -> bool; - /// Returns `false` if `self` is equal to the multiplicative identity. - fn is_non_one(self: @T) -> bool; -} diff --git a/corelib/src/num/traits/ops.cairo b/corelib/src/num/traits/ops.cairo deleted file mode 100644 index 7dba1d5a1..000000000 --- a/corelib/src/num/traits/ops.cairo +++ /dev/null @@ -1,2 +0,0 @@ -pub mod overflowing; -pub mod wrapping; diff --git a/corelib/src/num/traits/ops/overflowing.cairo b/corelib/src/num/traits/ops/overflowing.cairo deleted file mode 100644 index 02768b0a7..000000000 --- a/corelib/src/num/traits/ops/overflowing.cairo +++ /dev/null @@ -1,23 +0,0 @@ -/// Performs addition with a flag for overflow. -pub trait OverflowingAdd { - /// Returns a tuple of the sum along with a boolean indicating whether an arithmetic overflow - /// would occur. - /// If an overflow would have occurred then the wrapped value is returned. - fn overflowing_add(self: T, v: T) -> (T, bool); -} - -/// Performs subtraction with a flag for overflow. -pub trait OverflowingSub { - /// Returns a tuple of the difference along with a boolean indicating whether an arithmetic - /// overflow would occur. - /// If an overflow would have occurred then the wrapped value is returned. - fn overflowing_sub(self: T, v: T) -> (T, bool); -} - -/// Performs multiplication with a flag for overflow. -pub trait OverflowingMul { - /// Returns a tuple of the product along with a boolean indicating whether an arithmetic - /// overflow would occur. - /// If an overflow would have occurred then the wrapped value is returned. - fn overflowing_mul(self: T, v: T) -> (T, bool); -} diff --git a/corelib/src/num/traits/ops/wrapping.cairo b/corelib/src/num/traits/ops/wrapping.cairo deleted file mode 100644 index 0295d4a01..000000000 --- a/corelib/src/num/traits/ops/wrapping.cairo +++ /dev/null @@ -1,49 +0,0 @@ -/// Performs addition that wraps around on overflow. -pub trait WrappingAdd { - /// Wrapping (modular) addition. Computes `self + other`, wrapping around at the boundary of the - /// type. - fn wrapping_add(self: T, v: T) -> T; -} - -/// Performs subtraction that wraps around on overflow. -pub trait WrappingSub { - /// Wrapping (modular) subtraction. Computes `self - other`, wrapping around at the boundary of - /// the type. - fn wrapping_sub(self: T, v: T) -> T; -} - -/// Performs multiplication that wraps around on overflow. -pub trait WrappingMul { - /// Wrapping (modular) multiplication. Computes `self * other`, wrapping around at the boundary - /// of the type. - fn wrapping_mul(self: T, v: T) -> T; -} - -pub(crate) mod overflow_based { - pub(crate) impl TWrappingAdd< - T, +core::num::traits::OverflowingAdd - > of core::num::traits::WrappingAdd { - fn wrapping_add(self: T, v: T) -> T { - let (result, _) = self.overflowing_add(v); - result - } - } - - pub(crate) impl TWrappingSub< - T, +core::num::traits::OverflowingSub - > of core::num::traits::WrappingSub { - fn wrapping_sub(self: T, v: T) -> T { - let (result, _) = self.overflowing_sub(v); - result - } - } - - pub(crate) impl TWrappingMul< - T, +core::num::traits::OverflowingMul - > of core::num::traits::WrappingMul { - fn wrapping_mul(self: T, v: T) -> T { - let (result, _) = self.overflowing_mul(v); - result - } - } -} diff --git a/corelib/src/num/traits/zero.cairo b/corelib/src/num/traits/zero.cairo deleted file mode 100644 index c43bd5d30..000000000 --- a/corelib/src/num/traits/zero.cairo +++ /dev/null @@ -1,9 +0,0 @@ -/// Defines an additive identity element for `T`. -pub trait Zero { - /// Returns the additive identity element of `T`, `0`. - fn zero() -> T; - /// Returns `true` if `self` is equal to the additive identity. - fn is_zero(self: @T) -> bool; - /// Returns `false` if `self` is equal to the additive identity. - fn is_non_zero(self: @T) -> bool; -} diff --git a/corelib/src/option.cairo b/corelib/src/option.cairo deleted file mode 100644 index 6db7b302b..000000000 --- a/corelib/src/option.cairo +++ /dev/null @@ -1,91 +0,0 @@ -#[must_use] -#[derive(Copy, Drop, Debug, Serde, PartialEq)] -pub enum Option { - Some: T, - None, -} - -pub impl DestructOption, -Drop>> of Destruct> { - #[inline(always)] - fn destruct(self: Option) nopanic { - match self { - Option::Some(x) => x.destruct(), - Option::None => (), - }; - } -} - -pub trait OptionTrait { - /// If `val` is `Option::Some(x)`, returns `x`. Otherwise, panics with `err`. - fn expect(self: Option, err: felt252) -> T; - /// If `val` is `Option::Some(x)`, returns `x`. Otherwise, panics. - fn unwrap(self: Option) -> T; - /// Transforms the `Option` into a `Result`, mapping `Option::Some(v)` to - /// `Result::Ok(v)` and `Option::None` to `Result::Err(err)`. - fn ok_or>(self: Option, err: E) -> Result; - /// Returns `true` if the `Option` is `Option::Some`. - #[must_use] - fn is_some(self: @Option) -> bool; - /// Returns `true` if the `Option` is `Option::None`. - #[must_use] - fn is_none(self: @Option) -> bool; - /// If `self` is `Option::Some(x)`, returns `x`. Otherwise, returns the provided default. - fn unwrap_or<+Drop>(self: Option, default: T) -> T; - /// If `self` is `Option::Some(x)`, returns `x`. Otherwise, returns `Default::::default()`. - fn unwrap_or_default<+Default>(self: Option) -> T; -} - -pub impl OptionTraitImpl of OptionTrait { - #[inline(always)] - fn expect(self: Option, err: felt252) -> T { - match self { - Option::Some(x) => x, - Option::None => core::panic_with_felt252(err), - } - } - - #[inline(always)] - fn unwrap(self: Option) -> T { - self.expect('Option::unwrap failed.') - } - - #[inline] - fn ok_or>(self: Option, err: E) -> Result { - match self { - Option::Some(v) => Result::Ok(v), - Option::None => Result::Err(err), - } - } - - #[inline(always)] - fn is_some(self: @Option) -> bool { - match self { - Option::Some(_) => true, - Option::None => false, - } - } - - #[inline(always)] - fn is_none(self: @Option) -> bool { - match self { - Option::Some(_) => false, - Option::None => true, - } - } - - #[inline] - fn unwrap_or<+Drop>(self: Option, default: T) -> T { - match self { - Option::Some(x) => x, - Option::None => default, - } - } - - #[inline] - fn unwrap_or_default<+Default>(self: Option) -> T { - match self { - Option::Some(x) => x, - Option::None => Default::default(), - } - } -} diff --git a/corelib/src/panics.cairo b/corelib/src/panics.cairo deleted file mode 100644 index c6b49cc6e..000000000 --- a/corelib/src/panics.cairo +++ /dev/null @@ -1,19 +0,0 @@ -use core::array::Array; - -pub struct Panic {} - -pub enum PanicResult { - Ok: T, - Err: (Panic, Array), -} - -pub extern fn panic(data: Array) -> core::never; - -/// Panics with the given ByteArray. That is, panics with an `Array` with -/// `BYTE_ARRAY_MAGIC`, and then the serialized given ByteArray. -#[inline(always)] -pub fn panic_with_byte_array(err: @ByteArray) -> core::never { - let mut serialized = array![core::byte_array::BYTE_ARRAY_MAGIC]; - err.serialize(ref serialized); - panic(serialized) -} diff --git a/corelib/src/pedersen.cairo b/corelib/src/pedersen.cairo deleted file mode 100644 index 8a5bf72a5..000000000 --- a/corelib/src/pedersen.cairo +++ /dev/null @@ -1,32 +0,0 @@ -pub extern type Pedersen; - -pub extern fn pedersen(a: felt252, b: felt252) -> felt252 implicits(Pedersen) nopanic; - - -/// State for Pedersen hash. -#[derive(Copy, Drop, Debug)] -pub struct HashState { - pub state: felt252, -} - -#[generate_trait] -pub impl PedersenImpl of PedersenTrait { - /// Creates a state from a base value. - #[inline(always)] - fn new(base: felt252) -> HashState { - HashState { state: base } - } -} - -impl HashStateImpl of core::hash::HashStateTrait { - #[inline(always)] - fn update(self: HashState, value: felt252) -> HashState { - HashState { state: pedersen(self.state, value) } - } - - #[inline(always)] - fn finalize(self: HashState) -> felt252 { - self.state - } -} - diff --git a/corelib/src/poseidon.cairo b/corelib/src/poseidon.cairo deleted file mode 100644 index 9540160e2..000000000 --- a/corelib/src/poseidon.cairo +++ /dev/null @@ -1,87 +0,0 @@ -use core::array::Span; -use core::array::SpanTrait; -use core::option::OptionTrait; -use core::hash::HashStateTrait; - -pub extern type Poseidon; - -pub extern fn hades_permutation( - s0: felt252, s1: felt252, s2: felt252 -) -> (felt252, felt252, felt252) implicits(Poseidon) nopanic; - -/// State for Poseidon hash. -#[derive(Copy, Drop, Debug)] -pub struct HashState { - pub s0: felt252, - pub s1: felt252, - pub s2: felt252, - pub odd: bool, -} - -#[generate_trait] -pub impl PoseidonImpl of PoseidonTrait { - /// Creates an initial state. - #[inline(always)] - fn new() -> HashState { - HashState { s0: 0, s1: 0, s2: 0, odd: false } - } -} - -impl HashStateDefault of Default { - fn default() -> HashState { - PoseidonTrait::new() - } -} - -impl HashStateImpl of HashStateTrait { - #[inline(always)] - fn update(self: HashState, value: felt252) -> HashState { - if self.odd { - let (s0, s1, s2) = hades_permutation(self.s0, self.s1 + value, self.s2); - HashState { s0, s1, s2, odd: false } - } else { - HashState { s0: self.s0 + value, s1: self.s1, s2: self.s2, odd: true } - } - } - - #[inline(always)] - fn finalize(self: HashState) -> felt252 { - if self.odd { - let (r, _, _) = hades_permutation(self.s0, self.s1 + 1, self.s2); - r - } else { - let (r, _, _) = hades_permutation(self.s0 + 1, self.s1, self.s2); - r - } - } -} - -/// Computes the Poseidon hash on the given input. -/// -/// Applies the sponge construction to digest many elements. -/// To distinguish between use cases, the capacity element is initialized to 0. -/// To distinguish between different input sizes always pads with 1, and possibly with another 0 to -/// complete to an even-sized input. -pub fn poseidon_hash_span(mut span: Span) -> felt252 { - _poseidon_hash_span_inner(core::gas::get_builtin_costs(), (0, 0, 0), ref span) -} - -/// Helper function for poseidon_hash_span. -fn _poseidon_hash_span_inner( - builtin_costs: core::gas::BuiltinCosts, - state: (felt252, felt252, felt252), - ref span: Span -) -> felt252 { - let (s0, s1, s2) = state; - let x = *match span.pop_front() { - Option::Some(x) => x, - Option::None => { return HashState { s0, s1, s2, odd: false }.finalize(); }, - }; - let y = *match span.pop_front() { - Option::Some(y) => y, - Option::None => { return HashState { s0: s0 + x, s1, s2, odd: true }.finalize(); }, - }; - let next_state = hades_permutation(s0 + x, s1 + y, s2); - core::gas::withdraw_gas_all(builtin_costs).expect('Out of gas'); - _poseidon_hash_span_inner(builtin_costs, next_state, ref span) -} diff --git a/corelib/src/prelude.cairo b/corelib/src/prelude.cairo deleted file mode 100644 index c82d9325e..000000000 --- a/corelib/src/prelude.cairo +++ /dev/null @@ -1,2 +0,0 @@ -mod v2023_01; -mod v2023_10; diff --git a/corelib/src/prelude/v2023_01.cairo b/corelib/src/prelude/v2023_01.cairo deleted file mode 100644 index d2bf4f23e..000000000 --- a/corelib/src/prelude/v2023_01.cairo +++ /dev/null @@ -1,70 +0,0 @@ -use core::{ - BoolBitAnd, BoolBitOr, BoolBitXor, BoolFelt252DictValue, BoolIntoFelt252, BoolNot, - BoolPartialEq, BoolSerde, Felt252Add, Felt252AddEq, Felt252Default, Felt252Felt252DictValue, - Felt252Mul, Felt252MulEq, Felt252Neg, Felt252PartialEq, Felt252Serde, Felt252Sub, Felt252SubEq, - Felt252TryIntoNonZero, RangeCheck, SegmentArena, assert, bool, bool_and_impl, bool_not_impl, - bool_or_impl, bool_to_felt252, bool_xor_impl, drop, dup, felt252, felt252_add, felt252_const, - felt252_div, felt252_is_zero, felt252_mul, felt252_sub, never, panic_with_felt252, usize -}; - -use core::{array, array::{Array, ArrayTrait, Span, SpanTrait}}; -use core::{box, box::{Box, BoxTrait}}; -use core::{ - bytes_31, - bytes_31::{ - Bytes31IndexView, Bytes31IntoFelt252, Bytes31Trait, Felt252TryIntoBytes31, bytes31, - bytes31_const - } -}; -use core::{ - byte_array, byte_array::{ByteArray, ByteArrayIndexView, ByteArrayStringLiteral, ByteArrayTrait} -}; -use core::{clone, clone::Clone}; -use core::cmp; -use core::debug; -use core::{ - dict, - dict::{ - Felt252Dict, Felt252DictTrait, SquashedFelt252Dict, felt252_dict_new, felt252_dict_squash - } -}; -use core::{ec, ec::{EcOp, EcPoint, EcState}}; -use core::ecdsa; -use core::{gas, gas::{BuiltinCosts, GasBuiltin, get_builtin_costs}}; -use core::hash; -use core::{ - integer, - integer::{ - Bitwise, Felt252IntoU256, Felt252TryIntoU128, Felt252TryIntoU16, Felt252TryIntoU32, - Felt252TryIntoU64, Felt252TryIntoU8, I128IntoFelt252, I16IntoFelt252, I32IntoFelt252, - I64IntoFelt252, I8IntoFelt252, NumericLiteral, U128IntoFelt252, U16IntoFelt252, - U32IntoFelt252, U64IntoFelt252, U8IntoFelt252, i128, i16, i32, i64, i8, u128, u128_is_zero, - u128_sqrt, u16, u256, u256_sqrt, u32, u64, u8 - } -}; -use core::internal; -use core::keccak; -use core::math; -use core::{nullable, nullable::{Nullable, NullableTrait, match_nullable, null, nullable_from_box}}; -use core::{option, option::{Option, OptionTrait}}; -use core::{panics, panics::{Panic, PanicResult, panic}}; -use core::{pedersen, pedersen::Pedersen}; -use core::{poseidon, poseidon::Poseidon}; -use core::{result, result::{Result, ResultTrait}}; -use core::{serde, serde::Serde}; -use core::{starknet, starknet::System}; -use core::{string, string::StringLiteral}; -use core::testing; -use core::to_byte_array; -use core::{ - traits, - traits::{ - Add, AddEq, BitAnd, BitNot, BitOr, BitXor, Copy, Default, Destruct, Div, DivEq, DivRem, - Drop, Felt252DictValue, Index, IndexView, Into, Mul, MulEq, Neg, Not, PanicDestruct, - PartialEq, PartialOrd, Rem, RemEq, Sub, SubEq, TryInto, TupleSize0Copy, TupleSize0Drop - } -}; -use core::{zeroable, zeroable::{NonZero, Zeroable}}; - -#[cfg(test)] -use core::test; diff --git a/corelib/src/prelude/v2023_10.cairo b/corelib/src/prelude/v2023_10.cairo deleted file mode 100644 index 61e714dcd..000000000 --- a/corelib/src/prelude/v2023_10.cairo +++ /dev/null @@ -1,27 +0,0 @@ -pub use core::{RangeCheck, SegmentArena, assert, bool, felt252, usize}; - -pub use core::array::{Array, ArrayTrait, Span, SpanTrait}; -pub use core::box::{Box, BoxTrait}; -pub use core::bytes_31::{Bytes31Trait, bytes31}; -pub use core::byte_array::{ByteArray, ByteArrayTrait}; -pub use core::clone::Clone; -pub use core::dict::{Felt252Dict, Felt252DictTrait, SquashedFelt252Dict}; -pub use core::gas::GasBuiltin; -pub use core::integer::{Bitwise, i128, i16, i32, i64, i8, u128, u16, u256, u32, u64, u8}; -pub use core::keccak; -pub use core::math; -pub use core::nullable::{Nullable, NullableTrait}; -pub use core::option::{Option, OptionTrait}; -pub use core::panics::{Panic, PanicResult, panic}; -pub use core::pedersen::Pedersen; -pub use core::poseidon::Poseidon; -pub use core::result::{Result, ResultTrait}; -pub use core::serde::Serde; -pub use core::{starknet, starknet::System}; -pub use core::to_byte_array; -pub use core::traits::{ - Add, AddEq, BitAnd, BitNot, BitOr, BitXor, Copy, Default, Destruct, Div, DivEq, DivRem, Drop, - Felt252DictValue, Index, IndexView, Into, Mul, MulEq, Neg, Not, PanicDestruct, PartialEq, - PartialOrd, Rem, RemEq, Sub, SubEq, TryInto -}; -pub use core::zeroable::NonZero; diff --git a/corelib/src/result.cairo b/corelib/src/result.cairo deleted file mode 100644 index b9eb9aa22..000000000 --- a/corelib/src/result.cairo +++ /dev/null @@ -1,84 +0,0 @@ -use core::array::ArrayTrait; -use core::serde::Serde; -use core::array::SpanTrait; - -#[must_use] -#[derive(Copy, Drop, Debug, Serde, PartialEq)] -pub enum Result { - Ok: T, - Err: E, -} - -#[generate_trait] -pub impl ResultTraitImpl of ResultTrait { - /// If `val` is `Result::Ok(x)`, returns `x`. Otherwise, panics with `err`. - fn expect<+Drop>(self: Result, err: felt252) -> T { - match self { - Result::Ok(x) => x, - Result::Err(_) => core::panic_with_felt252(err), - } - } - /// If `val` is `Result::Ok(x)`, returns `x`. Otherwise, panics. - fn unwrap<+Drop>(self: Result) -> T { - self.expect('Result::unwrap failed.') - } - /// If `val` is `Result::Ok(x)`, returns `x`. Otherwise, returns `default`. - fn unwrap_or<+Drop, +Drop>(self: Result, default: T) -> T { - match self { - Result::Ok(x) => x, - Result::Err(_) => default, - } - } - /// If `val` is `Result::Ok(x)`, returns `x`. - /// Otherwise returns `Default::::default()`. - fn unwrap_or_default<+Drop, +Default>(self: Result) -> T { - match self { - Result::Ok(x) => x, - Result::Err(_) => Default::default(), - } - } - - /// If `val` is `Result::Err(x)`, returns `x`. Otherwise, panics with `err`. - fn expect_err<+Drop>(self: Result, err: felt252) -> E { - match self { - Result::Ok(_) => core::panic_with_felt252(err), - Result::Err(x) => x, - } - } - /// If `val` is `Result::Err(x)`, returns `x`. Otherwise, panics. - fn unwrap_err<+Drop>(self: Result) -> E { - self.expect_err('Result::unwrap_err failed.') - } - /// Returns `true` if the `Result` is `Result::Ok`. - #[inline] - fn is_ok(self: @Result) -> bool { - match self { - Result::Ok(_) => true, - Result::Err(_) => false, - } - } - /// Returns `true` if the `Result` is `Result::Err`. - #[inline] - fn is_err(self: @Result) -> bool { - match self { - Result::Ok(_) => false, - Result::Err(_) => true, - } - } - /// Returns `true` if the `Result` is `Result::Ok`, and consumes the value. - #[inline] - fn into_is_err<+Drop, +Drop>(self: Result) -> bool { - match self { - Result::Ok(_) => false, - Result::Err(_) => true, - } - } - /// Returns `true` if the `Result` is `Result::Err`, and consumes the value. - #[inline] - fn into_is_ok<+Drop, +Drop>(self: Result) -> bool { - match self { - Result::Ok(_) => true, - Result::Err(_) => false, - } - } -} diff --git a/corelib/src/serde.cairo b/corelib/src/serde.cairo deleted file mode 100644 index 98b0419dd..000000000 --- a/corelib/src/serde.cairo +++ /dev/null @@ -1,108 +0,0 @@ -use core::array::ArrayTrait; -use core::array::SpanTrait; - -pub trait Serde { - fn serialize(self: @T, ref output: Array); - fn deserialize(ref serialized: Span) -> Option; -} - -impl TupleSize0Serde of Serde<()> { - fn serialize(self: @(), ref output: Array) {} - fn deserialize(ref serialized: Span) -> Option<()> { - Option::Some(()) - } -} - -impl TupleSize1Serde> of Serde<(E0,)> { - fn serialize(self: @(E0,), ref output: Array) { - let (e0,) = self; - e0.serialize(ref output) - } - fn deserialize(ref serialized: Span) -> Option<(E0,)> { - Option::Some((Serde::deserialize(ref serialized)?,)) - } -} - -impl TupleSize2Serde, +Drop, +Serde, +Drop> of Serde<(E0, E1)> { - fn serialize(self: @(E0, E1), ref output: Array) { - let (e0, e1) = self; - e0.serialize(ref output); - e1.serialize(ref output) - } - fn deserialize(ref serialized: Span) -> Option<(E0, E1)> { - Option::Some((Serde::deserialize(ref serialized)?, Serde::deserialize(ref serialized)?)) - } -} - -impl TupleSize3Serde< - E0, E1, E2, +Serde, +Drop, +Serde, +Drop, +Serde, +Drop -> of Serde<(E0, E1, E2)> { - fn serialize(self: @(E0, E1, E2), ref output: Array) { - let (e0, e1, e2) = self; - e0.serialize(ref output); - e1.serialize(ref output); - e2.serialize(ref output) - } - fn deserialize(ref serialized: Span) -> Option<(E0, E1, E2)> { - Option::Some( - ( - Serde::deserialize(ref serialized)?, - Serde::deserialize(ref serialized)?, - Serde::deserialize(ref serialized)? - ) - ) - } -} - -impl TupleSize4Serde< - E0, - E1, - E2, - E3, - +Serde, - +Drop, - +Serde, - +Drop, - +Serde, - +Drop, - +Serde, - +Drop -> of Serde<(E0, E1, E2, E3)> { - fn serialize(self: @(E0, E1, E2, E3), ref output: Array) { - let (e0, e1, e2, e3) = self; - e0.serialize(ref output); - e1.serialize(ref output); - e2.serialize(ref output); - e3.serialize(ref output) - } - fn deserialize(ref serialized: Span) -> Option<(E0, E1, E2, E3)> { - Option::Some( - ( - Serde::deserialize(ref serialized)?, - Serde::deserialize(ref serialized)?, - Serde::deserialize(ref serialized)?, - Serde::deserialize(ref serialized)? - ) - ) - } -} - -/// Impl for `Serde` for types that can be converted into `felt252` using the `Into` trait and from `felt252` using the `TryInto` trait. -/// Usage example: -/// ```ignore -/// impl MyTypeSerde = core::serde::into_felt252_based::SerdeImpl;` -/// ``` -pub mod into_felt252_based { - use core::traits::{Into, TryInto}; - use core::array::ArrayTrait; - pub impl SerdeImpl, +Into, +TryInto> of super::Serde { - #[inline(always)] - fn serialize(self: @T, ref output: Array) { - output.append((*self).into()); - } - #[inline(always)] - fn deserialize(ref serialized: Span) -> Option { - Option::Some((*serialized.pop_front()?).try_into()?) - } - } -} diff --git a/corelib/src/starknet.cairo b/corelib/src/starknet.cairo deleted file mode 100644 index da248c263..000000000 --- a/corelib/src/starknet.cairo +++ /dev/null @@ -1,99 +0,0 @@ -use core::box::Box; -use core::option::OptionTrait; -use core::array::Span; -use core::traits::Into; -use core::traits::TryInto; -use core::zeroable::Zeroable; - -// Re-imports -// Store -pub mod storage_access; -pub use storage_access::{Store, StorageAddress}; -use storage_access::{ - StorePacking, StorageBaseAddress, storage_base_address_const, storage_base_address_from_felt252, - storage_address_from_base, storage_address_from_base_and_offset, storage_address_to_felt252, - storage_address_try_from_felt252 -}; - -// Module containing all the extern declaration of the syscalls. -pub mod syscalls; -use syscalls::{ - call_contract_syscall, deploy_syscall, emit_event_syscall, get_block_hash_syscall, - get_execution_info_syscall, library_call_syscall, send_message_to_l1_syscall, - storage_read_syscall, storage_write_syscall, replace_class_syscall, keccak_syscall -}; - -// secp256 -pub mod secp256_trait; -pub mod secp256k1; -pub mod secp256r1; - -// ContractAddress -pub mod contract_address; -pub use contract_address::{ContractAddress, contract_address_const}; -use contract_address::{ - ContractAddressIntoFelt252, Felt252TryIntoContractAddress, contract_address_to_felt252, - contract_address_try_from_felt252 -}; - -// EthAddress -pub mod eth_address; -pub use eth_address::EthAddress; -use eth_address::{ - EthAddressIntoFelt252, EthAddressSerde, EthAddressZeroable, Felt252TryIntoEthAddress -}; - -// EthSignature -pub mod eth_signature; -use eth_signature::verify_eth_signature; - -// ClassHash -pub mod class_hash; -pub use class_hash::ClassHash; -use class_hash::{ - ClassHashIntoFelt252, Felt252TryIntoClassHash, class_hash_const, class_hash_to_felt252, - class_hash_try_from_felt252 -}; - -// Not `pub` on purpose, only used for direct reexport by the next line. -mod info; -pub use info::{ - v2::ExecutionInfo as ExecutionInfo, BlockInfo, v2::TxInfo as TxInfo, get_execution_info, - get_caller_address, get_contract_address, get_block_info, get_tx_info, get_block_timestamp, - get_block_number -}; - -pub mod event; -pub use event::Event; - -pub mod account; -pub use account::AccountContract; - -pub mod storage; - -pub extern type System; - -// An Helper function to force the inclusion of `System` in the list of implicits. -fn use_system_implicit() implicits(System) {} - -/// The result type for a syscall. -pub type SyscallResult = Result>; - -pub trait SyscallResultTrait { - /// If `val` is `Result::Ok(x)`, returns `x`. Otherwise, panics with the revert reason. - fn unwrap_syscall(self: SyscallResult) -> T; -} -impl SyscallResultTraitImpl of SyscallResultTrait { - fn unwrap_syscall(self: SyscallResult) -> T { - match self { - Result::Ok(x) => x, - Result::Err(revert_reason) => panic(revert_reason), - } - } -} - -/// The expected return value of the `__validate*__` functions of an accounted contract. -pub const VALIDATED: felt252 = 'VALID'; - -// Module for starknet testing only. -pub mod testing; diff --git a/corelib/src/starknet/account.cairo b/corelib/src/starknet/account.cairo deleted file mode 100644 index 121efffc2..000000000 --- a/corelib/src/starknet/account.cairo +++ /dev/null @@ -1,15 +0,0 @@ -use starknet::ContractAddress; - -#[derive(Drop, Serde, Debug)] -pub struct Call { - pub to: ContractAddress, - pub selector: felt252, - pub calldata: Span -} - -#[starknet::interface] -pub trait AccountContract { - fn __validate_declare__(self: @TContractState, class_hash: felt252) -> felt252; - fn __validate__(ref self: TContractState, calls: Array) -> felt252; - fn __execute__(ref self: TContractState, calls: Array) -> Array>; -} diff --git a/corelib/src/starknet/class_hash.cairo b/corelib/src/starknet/class_hash.cairo deleted file mode 100644 index 17cdf9f4b..000000000 --- a/corelib/src/starknet/class_hash.cairo +++ /dev/null @@ -1,65 +0,0 @@ -use core::serde::Serde; -use core::hash::{Hash, HashStateTrait}; - -#[derive(Copy, Drop)] -pub extern type ClassHash; - -pub extern fn class_hash_const() -> ClassHash nopanic; -pub(crate) extern fn class_hash_to_felt252(address: ClassHash) -> felt252 nopanic; - -pub(crate) extern fn class_hash_try_from_felt252( - address: felt252 -) -> Option implicits(RangeCheck) nopanic; - -pub(crate) impl Felt252TryIntoClassHash of TryInto { - fn try_into(self: felt252) -> Option { - class_hash_try_from_felt252(self) - } -} -pub(crate) impl ClassHashIntoFelt252 of Into { - fn into(self: ClassHash) -> felt252 { - class_hash_to_felt252(self) - } -} - -impl ClassHashZero of core::num::traits::Zero { - fn zero() -> ClassHash { - class_hash_const::<0>() - } - #[inline(always)] - fn is_zero(self: @ClassHash) -> bool { - core::num::traits::Zero::::is_zero(@class_hash_to_felt252(*self)) - } - #[inline(always)] - fn is_non_zero(self: @ClassHash) -> bool { - !self.is_zero() - } -} - -pub(crate) impl ClassHashZeroable = - core::zeroable::zero_based::ZeroableImpl; - -impl ClassHashSerde of Serde { - fn serialize(self: @ClassHash, ref output: Array) { - class_hash_to_felt252(*self).serialize(ref output); - } - fn deserialize(ref serialized: Span) -> Option { - Option::Some(class_hash_try_from_felt252(Serde::::deserialize(ref serialized)?)?) - } -} - -impl ClassHashPartialEq of PartialEq { - #[inline(always)] - fn eq(lhs: @ClassHash, rhs: @ClassHash) -> bool { - class_hash_to_felt252(*lhs) == class_hash_to_felt252(*rhs) - } - #[inline(always)] - fn ne(lhs: @ClassHash, rhs: @ClassHash) -> bool { - !(lhs == rhs) - } -} - -impl HashClassHash, +Drop> = - core::hash::into_felt252_based::HashImpl; - -impl DebugClassHash = core::fmt::into_felt252_based::DebugImpl; diff --git a/corelib/src/starknet/contract_address.cairo b/corelib/src/starknet/contract_address.cairo deleted file mode 100644 index c4d7353d3..000000000 --- a/corelib/src/starknet/contract_address.cairo +++ /dev/null @@ -1,90 +0,0 @@ -use core::zeroable::Zeroable; -use core::serde::Serde; -use core::hash::{Hash, HashStateTrait}; - -#[derive(Copy, Drop)] -pub extern type ContractAddress; - - -pub extern fn contract_address_const() -> ContractAddress nopanic; -pub(crate) extern fn contract_address_to_felt252(address: ContractAddress) -> felt252 nopanic; - -pub(crate) extern fn contract_address_try_from_felt252( - address: felt252 -) -> Option implicits(RangeCheck) nopanic; - -pub(crate) impl Felt252TryIntoContractAddress of TryInto { - fn try_into(self: felt252) -> Option { - contract_address_try_from_felt252(self) - } -} -pub(crate) impl ContractAddressIntoFelt252 of Into { - fn into(self: ContractAddress) -> felt252 { - contract_address_to_felt252(self) - } -} - - -impl ContractAddressZero of core::num::traits::Zero { - fn zero() -> ContractAddress { - contract_address_const::<0>() - } - #[inline(always)] - fn is_zero(self: @ContractAddress) -> bool { - core::num::traits::Zero::::is_zero(@contract_address_to_felt252(*self)) - } - #[inline(always)] - fn is_non_zero(self: @ContractAddress) -> bool { - !self.is_zero() - } -} - -pub(crate) impl ContractAddressZeroable = - core::zeroable::zero_based::ZeroableImpl; - -impl ContractAddressSerde of Serde { - fn serialize(self: @ContractAddress, ref output: Array) { - contract_address_to_felt252(*self).serialize(ref output); - } - fn deserialize(ref serialized: Span) -> Option { - Option::Some( - contract_address_try_from_felt252(Serde::::deserialize(ref serialized)?)? - ) - } -} - -impl ContractAddressPartialEq of PartialEq { - #[inline(always)] - fn eq(lhs: @ContractAddress, rhs: @ContractAddress) -> bool { - contract_address_to_felt252(*lhs) == contract_address_to_felt252(*rhs) - } - #[inline(always)] - fn ne(lhs: @ContractAddress, rhs: @ContractAddress) -> bool { - !(lhs == rhs) - } -} - -impl ContractAddressPartialOrd of PartialOrd { - fn lt(lhs: ContractAddress, rhs: ContractAddress) -> bool { - // TODO(orizi): Check if implementing a libfunc for `felt252` ordering is more efficient. - let lhs: u256 = contract_address_to_felt252(lhs).into(); - lhs < contract_address_to_felt252(rhs).into() - } - #[inline(always)] - fn le(lhs: ContractAddress, rhs: ContractAddress) -> bool { - !(rhs < lhs) - } - #[inline(always)] - fn gt(lhs: ContractAddress, rhs: ContractAddress) -> bool { - rhs < lhs - } - #[inline(always)] - fn ge(lhs: ContractAddress, rhs: ContractAddress) -> bool { - !(lhs < rhs) - } -} - -impl HashContractAddress, +Drop> = - core::hash::into_felt252_based::HashImpl; - -impl DebugContractAddress = core::fmt::into_felt252_based::DebugImpl; diff --git a/corelib/src/starknet/eth_address.cairo b/corelib/src/starknet/eth_address.cairo deleted file mode 100644 index 2053506f7..000000000 --- a/corelib/src/starknet/eth_address.cairo +++ /dev/null @@ -1,69 +0,0 @@ -use core::debug::PrintTrait; -use core::integer::{u128_safe_divmod, U128TryIntoNonZero, U256TryIntoFelt252}; -use core::option::{Option, OptionTrait}; -use core::serde::Serde; -use core::traits::{Into, TryInto}; - -// An Ethereum address (160 bits). -#[derive(Copy, Drop, Hash, PartialEq, starknet::Store)] -pub struct EthAddress { - address: felt252, -} -pub(crate) impl Felt252TryIntoEthAddress of TryInto { - fn try_into(self: felt252) -> Option { - let ETH_ADDRESS_BOUND = 0x10000000000000000000000000000000000000000_u256; // 2 ** 160 - - if self.into() < ETH_ADDRESS_BOUND { - Option::Some(EthAddress { address: self }) - } else { - Option::None - } - } -} -pub(crate) impl EthAddressIntoFelt252 of Into { - fn into(self: EthAddress) -> felt252 { - self.address - } -} -pub(crate) impl U256IntoEthAddress of Into { - fn into(self: u256) -> EthAddress { - // The Ethereum address is the 20 least significant bytes (=160=128+32 bits) of the value. - let high_32_bits = self.high % 0x100000000_u128; - EthAddress { - address: high_32_bits.into() * 0x100000000000000000000000000000000_felt252 - + self.low.into() - } - } -} -pub(crate) impl EthAddressSerde of Serde { - fn serialize(self: @EthAddress, ref output: Array) { - self.address.serialize(ref output); - } - fn deserialize(ref serialized: Span) -> Option { - Serde::::deserialize(ref serialized)?.try_into() - } -} -impl EthAddressZero of core::num::traits::Zero { - fn zero() -> EthAddress { - 0.try_into().unwrap() - } - #[inline(always)] - fn is_zero(self: @EthAddress) -> bool { - core::num::traits::Zero::::is_zero(self.address) - } - #[inline(always)] - fn is_non_zero(self: @EthAddress) -> bool { - !self.is_zero() - } -} - -pub(crate) impl EthAddressZeroable = - core::zeroable::zero_based::ZeroableImpl; - -pub(crate) impl EthAddressPrintImpl of PrintTrait { - fn print(self: EthAddress) { - self.address.print(); - } -} - -impl DebugEthAddress = core::fmt::into_felt252_based::DebugImpl; diff --git a/corelib/src/starknet/eth_signature.cairo b/corelib/src/starknet/eth_signature.cairo deleted file mode 100644 index eaa91f391..000000000 --- a/corelib/src/starknet/eth_signature.cairo +++ /dev/null @@ -1,59 +0,0 @@ -use core::option::OptionTrait; -use starknet::{ - EthAddress, - secp256_trait::{ - Secp256Trait, Secp256PointTrait, recover_public_key, is_signature_entry_valid, Signature - }, - secp256k1::Secp256k1Point, SyscallResult, SyscallResultTrait -}; -use core::keccak::keccak_u256s_be_inputs; - -/// Asserts that an Ethereum signature is valid w.r.t. a given Eth address -/// Also verifies that r and s components of the signature are in the range (0, N), -/// where N is the size of the curve. -pub fn verify_eth_signature(msg_hash: u256, signature: Signature, eth_address: EthAddress) { - match is_eth_signature_valid(:msg_hash, :signature, :eth_address) { - Result::Ok(()) => {}, - Result::Err(err) => core::panic_with_felt252(err), - } -} - -/// Asserts that an Ethereum signature is valid w.r.t. a given Eth address -/// Also verifies that r and s components of the signature are in the range (0, N), -/// where N is the size of the curve. -/// Returns a Result with an error string if the signature is invalid. -pub fn is_eth_signature_valid( - msg_hash: u256, signature: Signature, eth_address: EthAddress -) -> Result<(), felt252> { - if !is_signature_entry_valid::(signature.r) { - return Result::Err('Signature out of range'); - } - if !is_signature_entry_valid::(signature.s) { - return Result::Err('Signature out of range'); - } - - let public_key_point = recover_public_key::(:msg_hash, :signature).unwrap(); - let calculated_eth_address = public_key_point_to_eth_address(:public_key_point); - if eth_address != calculated_eth_address { - return Result::Err('Invalid signature'); - } - Result::Ok(()) -} - -/// Converts a public key point to the corresponding Ethereum address. -pub fn public_key_point_to_eth_address< - Secp256Point, +Drop, +Secp256Trait, +Secp256PointTrait ->( - public_key_point: Secp256Point -) -> EthAddress { - let (x, y) = public_key_point.get_coordinates().unwrap_syscall(); - - // Keccak output is little endian. - let point_hash_le = keccak_u256s_be_inputs(array![x, y].span()); - let point_hash = u256 { - low: core::integer::u128_byte_reverse(point_hash_le.high), - high: core::integer::u128_byte_reverse(point_hash_le.low) - }; - - point_hash.into() -} diff --git a/corelib/src/starknet/event.cairo b/corelib/src/starknet/event.cairo deleted file mode 100644 index 157ca97d2..000000000 --- a/corelib/src/starknet/event.cairo +++ /dev/null @@ -1,8 +0,0 @@ -pub trait Event { - fn append_keys_and_data(self: @T, ref keys: Array, ref data: Array); - fn deserialize(ref keys: Span, ref data: Span) -> Option; -} - -pub trait EventEmitter { - fn emit>(ref self: T, event: S); -} diff --git a/corelib/src/starknet/info.cairo b/corelib/src/starknet/info.cairo deleted file mode 100644 index 631db1ba9..000000000 --- a/corelib/src/starknet/info.cairo +++ /dev/null @@ -1,133 +0,0 @@ -use starknet::{ - SyscallResultTrait, SyscallResult, syscalls::get_execution_info_syscall, - contract_address::ContractAddress -}; -use core::box::BoxTrait; - -#[derive(Copy, Drop, Debug)] -pub struct ExecutionInfo { - pub block_info: Box, - pub tx_info: Box, - pub caller_address: ContractAddress, - pub contract_address: ContractAddress, - pub entry_point_selector: felt252, -} - -#[derive(Copy, Drop, Debug, Serde)] -pub struct BlockInfo { - pub block_number: u64, - pub block_timestamp: u64, - pub sequencer_address: ContractAddress, -} - -#[derive(Copy, Drop, Debug, Serde)] -pub struct TxInfo { - // The version of the transaction. It is fixed (currently, 1) in the OS, and should be - // signed by the account contract. - // This field allows invalidating old transactions, whenever the meaning of the other - // transaction fields is changed (in the OS). - pub version: felt252, - // The account contract from which this transaction originates. - pub account_contract_address: ContractAddress, - // The max_fee field of the transaction. - pub max_fee: u128, - // The signature of the transaction. - pub signature: Span, - // The hash of the transaction. - pub transaction_hash: felt252, - // The identifier of the chain. - // This field can be used to prevent replay of testnet transactions on mainnet. - pub chain_id: felt252, - // The transaction's nonce. - pub nonce: felt252, -} - -pub fn get_execution_info() -> Box { - starknet::syscalls::get_execution_info_v2_syscall().unwrap_syscall() -} - -pub fn get_caller_address() -> ContractAddress { - get_execution_info().unbox().caller_address -} - -pub fn get_contract_address() -> ContractAddress { - get_execution_info().unbox().contract_address -} - -pub fn get_block_info() -> Box { - get_execution_info().unbox().block_info -} - -pub fn get_tx_info() -> Box { - get_execution_info().unbox().tx_info -} - -pub fn get_block_timestamp() -> u64 { - get_block_info().unbox().block_timestamp -} - -pub fn get_block_number() -> u64 { - get_block_info().unbox().block_number -} - -/// The extended version of the `get_execution_info` syscall result. -pub mod v2 { - use starknet::contract_address::ContractAddress; - use super::BlockInfo; - - #[derive(Copy, Drop, Debug)] - pub struct ExecutionInfo { - pub block_info: Box, - pub tx_info: Box, - pub caller_address: ContractAddress, - pub contract_address: ContractAddress, - pub entry_point_selector: felt252, - } - - #[derive(Copy, Drop, Debug, Serde)] - pub struct TxInfo { - // The version of the transaction. It is fixed (currently, 1) in the OS, and should be - // signed by the account contract. - // This field allows invalidating old transactions, whenever the meaning of the other - // transaction fields is changed (in the OS). - pub version: felt252, - // The account contract from which this transaction originates. - pub account_contract_address: ContractAddress, - // The max_fee field of the transaction. - pub max_fee: u128, - // The signature of the transaction. - pub signature: Span, - // The hash of the transaction. - pub transaction_hash: felt252, - // The identifier of the chain. - // This field can be used to prevent replay of testnet transactions on mainnet. - pub chain_id: felt252, - // The transaction's nonce. - pub nonce: felt252, - // A span of ResourceBounds structs. - pub resource_bounds: Span, - // The tip. - pub tip: u128, - // If specified, the paymaster should pay for the execution of the tx. - // The data includes the address of the paymaster sponsoring the transaction, followed by - // extra data to send to the paymaster. - pub paymaster_data: Span, - // The data availability mode for the nonce. - pub nonce_data_availability_mode: u32, - // The data availability mode for the account balance from which fee will be taken. - pub fee_data_availability_mode: u32, - // If nonempty, will contain the required data for deploying and initializing an account - // contract: its class hash, address salt and constructor calldata. - pub account_deployment_data: Span, - } - - #[derive(Copy, Drop, Debug, Serde)] - pub struct ResourceBounds { - // The name of the resource. - pub resource: felt252, - // The maximum amount of the resource allowed for usage during the execution. - pub max_amount: u64, - // The maximum price the user is willing to pay for the resource unit. - pub max_price_per_unit: u128, - } -} diff --git a/corelib/src/starknet/secp256_trait.cairo b/corelib/src/starknet/secp256_trait.cairo deleted file mode 100644 index eba4722c3..000000000 --- a/corelib/src/starknet/secp256_trait.cairo +++ /dev/null @@ -1,121 +0,0 @@ -use core::array::ArrayTrait; -use core::math::{u256_mul_mod_n, u256_inv_mod}; -use core::option::OptionTrait; -use starknet::{eth_address::U256IntoEthAddress, EthAddress, SyscallResult, SyscallResultTrait}; -use core::traits::{Into, TryInto}; -use core::integer::U256TryIntoNonZero; - -/// Secp256{k/r}1 ECDSA signature. -#[derive(Copy, Drop, Debug, PartialEq, Serde, starknet::Store, Hash)] -pub struct Signature { - pub r: u256, - pub s: u256, - // The parity of the y coordinate of the ec point whose x coordinate is `r`. - // `y_parity` == true means that the y coordinate is odd. - // Some places use non boolean v instead of y_parity. - // In that case, `signature_from_vrs` should be used. - pub y_parity: bool, -} - - -/// Creates an ECDSA signature from the `v`, `r` and `s` values. -/// `v` is the sum of an odd number and the parity of the y coordinate of the ec point whose x -/// coordinate is `r`. -/// See https://eips.ethereum.org/EIPS/eip-155 for more details. -pub fn signature_from_vrs(v: u32, r: u256, s: u256) -> Signature { - Signature { r, s, y_parity: v % 2 == 0 } -} - -pub trait Secp256Trait { - fn get_curve_size() -> u256; - fn get_generator_point() -> Secp256Point; - - fn secp256_ec_new_syscall(x: u256, y: u256) -> SyscallResult>; - fn secp256_ec_get_point_from_x_syscall( - x: u256, y_parity: bool - ) -> SyscallResult>; -} - -pub trait Secp256PointTrait { - fn get_coordinates(self: Secp256Point) -> SyscallResult<(u256, u256)>; - fn add(self: Secp256Point, other: Secp256Point) -> SyscallResult; - fn mul(self: Secp256Point, scalar: u256) -> SyscallResult; -} - -/// Checks whether `value` is in the range [1, N), where N is the size of the curve. -pub fn is_signature_entry_valid< - Secp256Point, +Drop, impl Secp256Impl: Secp256Trait ->( - value: u256 -) -> bool { - value != 0_u256 && value < Secp256Impl::get_curve_size() -} - -pub fn is_valid_signature< - Secp256Point, - +Drop, - impl Secp256Impl: Secp256Trait, - +Secp256PointTrait ->( - msg_hash: u256, r: u256, s: u256, public_key: Secp256Point -) -> bool { - if !is_signature_entry_valid::(r) - || !is_signature_entry_valid::(s) { - return false; - } - - let n_nz = Secp256Impl::get_curve_size().try_into().unwrap(); - let s_inv = u256_inv_mod(s.try_into().unwrap(), n_nz).unwrap().into(); - let u1 = u256_mul_mod_n(msg_hash, s_inv, n_nz); - let u2 = u256_mul_mod_n(r, s_inv, n_nz); - - let generator_point = Secp256Impl::get_generator_point(); - let point1 = generator_point.mul(u1).unwrap_syscall(); - let point2 = public_key.mul(u2).unwrap_syscall(); - let sum = point1.add(point2).unwrap_syscall(); - - let (x, _y) = sum.get_coordinates().unwrap_syscall(); - x == r -} - -/// Receives a signature and the signed message hash. -/// Returns the public key associated with the signer, represented as a point on the curve. -pub fn recover_public_key< - Secp256Point, - +Drop, - impl Secp256Impl: Secp256Trait, - +Secp256PointTrait ->( - msg_hash: u256, signature: Signature -) -> Option { - let Signature { r, s, y_parity } = signature; - let r_point = Secp256Impl::secp256_ec_get_point_from_x_syscall(x: r, :y_parity) - .unwrap_syscall()?; - let generator_point = Secp256Impl::get_generator_point(); - - // The result is given by - // -(msg_hash / r) * gen + (s / r) * r_point - // where the divisions by `r` are modulo `N` (the size of the curve). - - let n_nz = Secp256Impl::get_curve_size().try_into().unwrap(); - let r_inv = u256_inv_mod(r.try_into().unwrap(), n_nz).unwrap().into(); - - let u1 = u256_mul_mod_n(msg_hash, r_inv, n_nz); - let minus_u1 = secp256_ec_negate_scalar::(u1); - let u2 = u256_mul_mod_n(s, r_inv, n_nz); - - let minus_point1 = generator_point.mul(minus_u1).unwrap_syscall(); - - let point2 = r_point.mul(u2).unwrap_syscall(); - - Option::Some(minus_point1.add(point2).unwrap_syscall()) -} - -/// Computes the negation of a scalar modulo N (the size of the curve). -fn secp256_ec_negate_scalar< - Secp256Point, +Drop, impl Secp256Impl: Secp256Trait ->( - c: u256 -) -> u256 { - Secp256Impl::get_curve_size() - c -} diff --git a/corelib/src/starknet/secp256k1.cairo b/corelib/src/starknet/secp256k1.cairo deleted file mode 100644 index a3a4f24a7..000000000 --- a/corelib/src/starknet/secp256k1.cairo +++ /dev/null @@ -1,77 +0,0 @@ -//! This module contains functions and constructs related to elliptic curve operations on the -//! secp256k1 curve. - -use core::option::OptionTrait; -use starknet::{ - secp256_trait::{ - Secp256Trait, Secp256PointTrait, recover_public_key, is_signature_entry_valid, Signature - }, - SyscallResult, SyscallResultTrait -}; - -#[derive(Copy, Drop)] -pub extern type Secp256k1Point; - -pub(crate) impl Secp256k1Impl of Secp256Trait { - // TODO(yuval): change to constant once u256 constants are supported. - fn get_curve_size() -> u256 { - 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141 - } - /// Creates the generator point of the secp256k1 curve. - fn get_generator_point() -> Secp256k1Point { - secp256k1_new_syscall( - 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798, - 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 - ) - .unwrap_syscall() - .unwrap() - } - - fn secp256_ec_new_syscall(x: u256, y: u256) -> SyscallResult> { - secp256k1_new_syscall(x, y) - } - fn secp256_ec_get_point_from_x_syscall( - x: u256, y_parity: bool - ) -> SyscallResult> { - secp256k1_get_point_from_x_syscall(x, y_parity) - } -} - -pub(crate) impl Secp256k1PointImpl of Secp256PointTrait { - fn get_coordinates(self: Secp256k1Point) -> SyscallResult<(u256, u256)> { - secp256k1_get_xy_syscall(self) - } - fn add(self: Secp256k1Point, other: Secp256k1Point) -> SyscallResult { - secp256k1_add_syscall(self, other) - } - fn mul(self: Secp256k1Point, scalar: u256) -> SyscallResult { - secp256k1_mul_syscall(self, scalar) - } -} - -/// Creates a secp256k1 EC point from the given x and y coordinates. -/// Returns None if the given coordinates do not correspond to a point on the curve. -extern fn secp256k1_new_syscall( - x: u256, y: u256 -) -> SyscallResult> implicits(GasBuiltin, System) nopanic; - -/// Computes the addition of secp256k1 EC points `p0 + p1`. -extern fn secp256k1_add_syscall( - p0: Secp256k1Point, p1: Secp256k1Point -) -> SyscallResult implicits(GasBuiltin, System) nopanic; -/// Computes the product of a secp256k1 EC point `p` by the given scalar `scalar`. -extern fn secp256k1_mul_syscall( - p: Secp256k1Point, scalar: u256 -) -> SyscallResult implicits(GasBuiltin, System) nopanic; - -/// Computes the point on the secp256k1 curve that matches the given `x` coordinate, if such exists. -/// Out of the two possible y's, chooses according to `y_parity`. -/// `y_parity` == true means that the y coordinate is odd. -extern fn secp256k1_get_point_from_x_syscall( - x: u256, y_parity: bool -) -> SyscallResult> implicits(GasBuiltin, System) nopanic; - -/// Returns the coordinates of a point on the secp256k1 curve. -extern fn secp256k1_get_xy_syscall( - p: Secp256k1Point -) -> SyscallResult<(u256, u256)> implicits(GasBuiltin, System) nopanic; diff --git a/corelib/src/starknet/secp256r1.cairo b/corelib/src/starknet/secp256r1.cairo deleted file mode 100644 index 362fe7990..000000000 --- a/corelib/src/starknet/secp256r1.cairo +++ /dev/null @@ -1,74 +0,0 @@ -//! This module contains functions and constructs related to elliptic curve operations on the -//! secp256r1 curve. - -use core::option::OptionTrait; -use starknet::{ - EthAddress, secp256_trait::{Secp256Trait, Secp256PointTrait}, SyscallResult, SyscallResultTrait -}; - -#[derive(Copy, Drop)] -pub extern type Secp256r1Point; - -pub(crate) impl Secp256r1Impl of Secp256Trait { - // TODO(yuval): change to constant once u256 constants are supported. - fn get_curve_size() -> u256 { - 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551 - } - /// Creates the generator point of the secp256r1 curve. - fn get_generator_point() -> Secp256r1Point { - secp256r1_new_syscall( - 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296, - 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5, - ) - .unwrap_syscall() - .unwrap() - } - - fn secp256_ec_new_syscall(x: u256, y: u256) -> SyscallResult> { - secp256r1_new_syscall(x, y) - } - fn secp256_ec_get_point_from_x_syscall( - x: u256, y_parity: bool - ) -> SyscallResult> { - secp256r1_get_point_from_x_syscall(x, y_parity) - } -} - -pub(crate) impl Secp256r1PointImpl of Secp256PointTrait { - fn get_coordinates(self: Secp256r1Point) -> SyscallResult<(u256, u256)> { - secp256r1_get_xy_syscall(self) - } - fn add(self: Secp256r1Point, other: Secp256r1Point) -> SyscallResult { - secp256r1_add_syscall(self, other) - } - fn mul(self: Secp256r1Point, scalar: u256) -> SyscallResult { - secp256r1_mul_syscall(self, scalar) - } -} - -/// Creates a secp256r1 EC point from the given x and y coordinates. -/// Returns None if the given coordinates do not correspond to a point on the curve. -extern fn secp256r1_new_syscall( - x: u256, y: u256 -) -> SyscallResult> implicits(GasBuiltin, System) nopanic; - -/// Computes the addition of secp256r1 EC points `p0 + p1`. -extern fn secp256r1_add_syscall( - p0: Secp256r1Point, p1: Secp256r1Point -) -> SyscallResult implicits(GasBuiltin, System) nopanic; -/// Computes the product of a secp256r1 EC point `p` by the given scalar `scalar`. -extern fn secp256r1_mul_syscall( - p: Secp256r1Point, scalar: u256 -) -> SyscallResult implicits(GasBuiltin, System) nopanic; - -/// Computes the point on the secp256r1 curve that matches the given `x` coordinate, if such exists. -/// Out of the two possible y's, chooses according to `y_parity`. -/// `y_parity` == true means that the y coordinate is odd. -extern fn secp256r1_get_point_from_x_syscall( - x: u256, y_parity: bool -) -> SyscallResult> implicits(GasBuiltin, System) nopanic; - -/// Returns the coordinates of a point on the secp256r1 curve. -extern fn secp256r1_get_xy_syscall( - p: Secp256r1Point -) -> SyscallResult<(u256, u256)> implicits(GasBuiltin, System) nopanic; diff --git a/corelib/src/starknet/storage.cairo b/corelib/src/starknet/storage.cairo deleted file mode 100644 index ac2dabc25..000000000 --- a/corelib/src/starknet/storage.cairo +++ /dev/null @@ -1,71 +0,0 @@ -/// Trait for getting the address of any contract/component storage member. -pub trait StorageMemberAddressTrait { - fn address(self: @TMemberState) -> starknet::StorageBaseAddress nopanic; -} - -/// Trait for accessing any contract/component storage member. -pub trait StorageMemberAccessTrait { - fn read(self: @TMemberState) -> TValue; - fn write(ref self: TMemberState, value: TValue); -} - -/// Implementation of StorageMemberAccessTrait for types that implement StorageMemberAddressTrait. -pub impl StorageMemberAccessImpl< - TMemberState, - TValue, - +StorageMemberAddressTrait, - +starknet::Store, - +Drop, -> of StorageMemberAccessTrait { - fn read(self: @TMemberState) -> TValue { - // Only address_domain 0 is currently supported. - let address_domain = 0_u32; - starknet::SyscallResultTrait::unwrap_syscall( - starknet::Store::::read(address_domain, self.address()) - ) - } - fn write(ref self: TMemberState, value: TValue) { - // Only address_domain 0 is currently supported. - let address_domain = 0_u32; - let write_result = starknet::Store::::write(address_domain, self.address(), value); - starknet::SyscallResultTrait::unwrap_syscall(write_result) - } -} - -/// Trait for getting the address of any contract/component mapping storage member. -pub trait StorageMapMemberAddressTrait { - fn address(self: @TMemberState, key: TKey) -> starknet::StorageBaseAddress; -} - -/// Trait for accessing any contract/component storage member. -pub trait StorageMapMemberAccessTrait { - fn read(self: @TMemberState, key: TKey) -> TValue; - fn write(ref self: TMemberState, key: TKey, value: TValue); -} - -/// Implementation of StorageMapMemberAccessTrait for types that implement -/// StorageMapMemberAddressTrait. -pub impl StorageMapMemberAccessImpl< - TMemberState, - TKey, - TValue, - +StorageMapMemberAddressTrait, - +starknet::Store, - +Drop, - +PanicDestruct, -> of StorageMapMemberAccessTrait { - fn read(self: @TMemberState, key: TKey) -> TValue { - // Only address_domain 0 is currently supported. - let address_domain = 0_u32; - starknet::SyscallResultTrait::unwrap_syscall( - starknet::Store::::read(address_domain, self.address(key)) - ) - } - fn write(ref self: TMemberState, key: TKey, value: TValue) { - // Only address_domain 0 is currently supported. - let address_domain = 0_u32; - starknet::SyscallResultTrait::unwrap_syscall( - starknet::Store::::write(address_domain, self.address(key), value) - ) - } -} diff --git a/corelib/src/starknet/storage_access.cairo b/corelib/src/starknet/storage_access.cairo deleted file mode 100644 index ad8836792..000000000 --- a/corelib/src/starknet/storage_access.cairo +++ /dev/null @@ -1,813 +0,0 @@ -use core::array::ArrayTrait; -use core::traits::{Into, TryInto}; -use core::option::OptionTrait; -use core::byte_array::ByteArrayTrait; -use core::bytes_31::BYTES_IN_BYTES31; -use starknet::{ - SyscallResult, syscalls::{storage_read_syscall, storage_write_syscall}, - contract_address::{ContractAddress, Felt252TryIntoContractAddress, ContractAddressIntoFelt252}, - class_hash::{ClassHash, Felt252TryIntoClassHash, ClassHashIntoFelt252} -}; -use core::serde::Serde; - -#[derive(Copy, Drop)] -pub extern type StorageAddress; - -#[derive(Copy, Drop)] -pub extern type StorageBaseAddress; - -// Storage. -pub extern fn storage_base_address_const() -> StorageBaseAddress nopanic; -pub extern fn storage_base_address_from_felt252( - addr: felt252 -) -> StorageBaseAddress implicits(RangeCheck) nopanic; - -pub(crate) extern fn storage_address_to_felt252(address: StorageAddress) -> felt252 nopanic; -pub extern fn storage_address_from_base_and_offset( - base: StorageBaseAddress, offset: u8 -) -> StorageAddress nopanic; - -pub extern fn storage_address_from_base(base: StorageBaseAddress) -> StorageAddress nopanic; - -pub(crate) extern fn storage_address_try_from_felt252( - address: felt252 -) -> Option implicits(RangeCheck) nopanic; - -impl Felt252TryIntoStorageAddress of TryInto { - fn try_into(self: felt252) -> Option { - storage_address_try_from_felt252(self) - } -} -impl StorageAddressIntoFelt252 of Into { - fn into(self: StorageAddress) -> felt252 { - storage_address_to_felt252(self) - } -} - -impl StorageAddressSerde of Serde { - fn serialize(self: @StorageAddress, ref output: Array) { - storage_address_to_felt252(*self).serialize(ref output); - } - fn deserialize(ref serialized: Span) -> Option { - Option::Some( - storage_address_try_from_felt252(Serde::::deserialize(ref serialized)?)? - ) - } -} - -impl DebugStorageAddress = core::fmt::into_felt252_based::DebugImpl; -impl DebugStorageBaseAddress of core::fmt::Debug { - fn fmt(self: @StorageBaseAddress, ref f: core::fmt::Formatter) -> Result<(), core::fmt::Error> { - DebugStorageAddress::fmt(@storage_address_from_base(*self), ref f) - } -} - -/// Trait for types that can be used as a value in Starknet storage variables. -pub trait Store { - /// Reads a value from storage from domain `address_domain` and base address `base`. - fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult; - /// Writes a value to storage to domain `address_domain` and base address `base`. - fn write(address_domain: u32, base: StorageBaseAddress, value: T) -> SyscallResult<()>; - /// Reads a value from storage from domain `address_domain` and base address `base` at offset - /// `offset`. - fn read_at_offset( - address_domain: u32, base: StorageBaseAddress, offset: u8 - ) -> SyscallResult; - /// Writes a value to storage to domain `address_domain` and base address `base` at offset - /// `offset`. - fn write_at_offset( - address_domain: u32, base: StorageBaseAddress, offset: u8, value: T - ) -> SyscallResult<()>; - fn size() -> u8; -} - -/// Trait for easier implementation of `Store` used for packing and unpacking values into values -/// that already implement `Store`, and having `Store` implemented using this conversion. -pub trait StorePacking { - /// Packs a value of type `T` into a value of type `PackedT`. - fn pack(value: T) -> PackedT; - /// Unpacks a value of type `PackedT` into a value of type `T`. - fn unpack(value: PackedT) -> T; -} - -impl StoreUsingPacking< - T, PackedT, impl TPacking: StorePacking, impl PackedTStore: Store -> of Store { - #[inline(always)] - fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult { - Result::Ok(TPacking::unpack(PackedTStore::read(address_domain, base)?)) - } - #[inline(always)] - fn write(address_domain: u32, base: StorageBaseAddress, value: T) -> SyscallResult<()> { - PackedTStore::write(address_domain, base, TPacking::pack(value)) - } - #[inline(always)] - fn read_at_offset( - address_domain: u32, base: StorageBaseAddress, offset: u8 - ) -> SyscallResult { - Result::Ok(TPacking::unpack(PackedTStore::read_at_offset(address_domain, base, offset)?)) - } - #[inline(always)] - fn write_at_offset( - address_domain: u32, base: StorageBaseAddress, offset: u8, value: T - ) -> SyscallResult<()> { - PackedTStore::write_at_offset(address_domain, base, offset, TPacking::pack(value)) - } - #[inline(always)] - fn size() -> u8 { - PackedTStore::size() - } -} - -impl StoreFelt252 of Store { - #[inline(always)] - fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult { - storage_read_syscall(address_domain, storage_address_from_base(base)) - } - #[inline(always)] - fn write(address_domain: u32, base: StorageBaseAddress, value: felt252) -> SyscallResult<()> { - storage_write_syscall(address_domain, storage_address_from_base(base), value) - } - #[inline(always)] - fn read_at_offset( - address_domain: u32, base: StorageBaseAddress, offset: u8 - ) -> SyscallResult { - storage_read_syscall(address_domain, storage_address_from_base_and_offset(base, offset)) - } - #[inline(always)] - fn write_at_offset( - address_domain: u32, base: StorageBaseAddress, offset: u8, value: felt252 - ) -> SyscallResult<()> { - storage_write_syscall( - address_domain, storage_address_from_base_and_offset(base, offset), value - ) - } - #[inline(always)] - fn size() -> u8 { - 1_u8 - } -} - -impl StorePackingBool of StorePacking { - fn pack(value: bool) -> felt252 { - value.into() - } - #[inline] - fn unpack(value: felt252) -> bool { - value != 0 - } -} - -impl StorePackingU8 of StorePacking { - fn pack(value: u8) -> felt252 { - value.into() - } - #[inline] - fn unpack(value: felt252) -> u8 { - value.try_into().expect('StoreU8 - non u8') - } -} - -impl StorePackingI8 of StorePacking { - fn pack(value: i8) -> felt252 { - value.into() - } - #[inline] - fn unpack(value: felt252) -> i8 { - value.try_into().expect('StoreI8 - non i8') - } -} - -impl StorePackingU16 of StorePacking { - fn pack(value: u16) -> felt252 { - value.into() - } - #[inline] - fn unpack(value: felt252) -> u16 { - value.try_into().expect('StoreU16 - non u16') - } -} - -impl StorePackingI16 of StorePacking { - fn pack(value: i16) -> felt252 { - value.into() - } - #[inline] - fn unpack(value: felt252) -> i16 { - value.try_into().expect('StoreI16 - non i16') - } -} - -impl StorePackingU32 of StorePacking { - fn pack(value: u32) -> felt252 { - value.into() - } - #[inline] - fn unpack(value: felt252) -> u32 { - value.try_into().expect('StoreU32 - non u32') - } -} - -impl StorePackingI32 of StorePacking { - fn pack(value: i32) -> felt252 { - value.into() - } - #[inline] - fn unpack(value: felt252) -> i32 { - value.try_into().expect('StoreI32 - non i32') - } -} - -impl StorePackingU64 of StorePacking { - fn pack(value: u64) -> felt252 { - value.into() - } - #[inline] - fn unpack(value: felt252) -> u64 { - value.try_into().expect('StoreU64 - non u64') - } -} - -impl StorePackingI64 of StorePacking { - fn pack(value: i64) -> felt252 { - value.into() - } - #[inline] - fn unpack(value: felt252) -> i64 { - value.try_into().expect('StoreI64 - non i64') - } -} - -impl StorePackingU128 of StorePacking { - fn pack(value: u128) -> felt252 { - value.into() - } - #[inline] - fn unpack(value: felt252) -> u128 { - value.try_into().expect('StoreU128 - non u128') - } -} - -impl StorePackingI128 of StorePacking { - fn pack(value: i128) -> felt252 { - value.into() - } - #[inline] - fn unpack(value: felt252) -> i128 { - value.try_into().expect('StoreI128 - non i128') - } -} - -impl StorePackingBytes31 of StorePacking { - fn pack(value: bytes31) -> felt252 { - value.into() - } - #[inline] - fn unpack(value: felt252) -> bytes31 { - value.try_into().expect('StoreBytes31 - non bytes31') - } -} - -impl StorePackingNonZero>> of StorePacking, T> { - fn pack(value: NonZero) -> T { - value.into() - } - #[inline] - fn unpack(value: T) -> NonZero { - value.try_into().expect('StoreNonZero - zero value') - } -} - -impl StorePackingStorageAddress of StorePacking { - fn pack(value: StorageAddress) -> felt252 { - value.into() - } - #[inline] - fn unpack(value: felt252) -> StorageAddress { - value.try_into().expect('Non StorageAddress') - } -} - -impl StorePackingContractAddress of StorePacking { - fn pack(value: ContractAddress) -> felt252 { - value.into() - } - #[inline] - fn unpack(value: felt252) -> ContractAddress { - value.try_into().expect('Non ContractAddress') - } -} - -impl StorePackingClassHash of StorePacking { - fn pack(value: ClassHash) -> felt252 { - value.into() - } - #[inline] - fn unpack(value: felt252) -> ClassHash { - value.try_into().expect('Non ClassHash') - } -} - -impl TupleSize0Store of Store<()> { - #[inline(always)] - fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult<()> { - Result::Ok(()) - } - #[inline(always)] - fn write(address_domain: u32, base: StorageBaseAddress, value: ()) -> SyscallResult<()> { - Result::Ok(()) - } - #[inline(always)] - fn read_at_offset( - address_domain: u32, base: StorageBaseAddress, offset: u8 - ) -> SyscallResult<()> { - Result::Ok(()) - } - #[inline(always)] - fn write_at_offset( - address_domain: u32, base: StorageBaseAddress, offset: u8, value: () - ) -> SyscallResult<()> { - Result::Ok(()) - } - #[inline(always)] - fn size() -> u8 { - 0 - } -} - -impl TupleSize1Store, +Drop> of Store<(E0,)> { - #[inline(always)] - fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult<(E0,)> { - Result::Ok((E0Store::read(address_domain, base)?,)) - } - #[inline(always)] - fn write(address_domain: u32, base: StorageBaseAddress, value: (E0,)) -> SyscallResult<()> { - let (e0,) = value; - E0Store::write(address_domain, base, e0) - } - #[inline(always)] - fn read_at_offset( - address_domain: u32, base: StorageBaseAddress, offset: u8 - ) -> SyscallResult<(E0,)> { - Result::Ok((E0Store::read_at_offset(address_domain, base, offset)?,)) - } - #[inline(always)] - fn write_at_offset( - address_domain: u32, base: StorageBaseAddress, offset: u8, value: (E0,) - ) -> SyscallResult<()> { - let (e0,) = value; - E0Store::write_at_offset(address_domain, base, offset, e0) - } - #[inline(always)] - fn size() -> u8 { - E0Store::size() - } -} - -impl TupleSize2Store< - E0, E1, impl E0Store: Store, +Drop, impl E1Store: Store, +Drop -> of Store<(E0, E1)> { - #[inline(always)] - fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult<(E0, E1)> { - let e0 = E0Store::read(address_domain, base)?; - let e1 = E1Store::read_at_offset(address_domain, base, E0Store::size())?; - Result::Ok((e0, e1)) - } - #[inline(always)] - fn write(address_domain: u32, base: StorageBaseAddress, value: (E0, E1)) -> SyscallResult<()> { - let (e0, e1) = value; - E0Store::write(address_domain, base, e0)?; - E1Store::write_at_offset(address_domain, base, E0Store::size(), e1) - } - #[inline(always)] - fn read_at_offset( - address_domain: u32, base: StorageBaseAddress, mut offset: u8 - ) -> SyscallResult<(E0, E1)> { - let e0 = E0Store::read_at_offset(address_domain, base, offset)?; - offset += E0Store::size(); - let e1 = E1Store::read_at_offset(address_domain, base, offset)?; - Result::Ok((e0, e1)) - } - #[inline(always)] - fn write_at_offset( - address_domain: u32, base: StorageBaseAddress, mut offset: u8, value: (E0, E1) - ) -> SyscallResult<()> { - let (e0, e1) = value; - E0Store::write_at_offset(address_domain, base, offset, e0)?; - offset += E0Store::size(); - E1Store::write_at_offset(address_domain, base, offset, e1) - } - #[inline(always)] - fn size() -> u8 { - E0Store::size() + E1Store::size() - } -} - -impl TupleSize3Store< - E0, - E1, - E2, - impl E0Store: Store, - +Drop, - impl E1Store: Store, - +Drop, - impl E2Store: Store, - +Drop -> of Store<(E0, E1, E2)> { - #[inline(always)] - fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult<(E0, E1, E2)> { - let e0 = E0Store::read(address_domain, base)?; - let mut offset = E0Store::size(); - let e1 = E1Store::read_at_offset(address_domain, base, offset)?; - offset += E1Store::size(); - let e2 = E2Store::read_at_offset(address_domain, base, offset)?; - Result::Ok((e0, e1, e2)) - } - #[inline(always)] - fn write( - address_domain: u32, base: StorageBaseAddress, value: (E0, E1, E2) - ) -> SyscallResult<()> { - let (e0, e1, e2) = value; - E0Store::write(address_domain, base, e0)?; - let mut offset = E0Store::size(); - E1Store::write_at_offset(address_domain, base, offset, e1)?; - offset += E1Store::size(); - E2Store::write_at_offset(address_domain, base, offset, e2) - } - #[inline(always)] - fn read_at_offset( - address_domain: u32, base: StorageBaseAddress, mut offset: u8 - ) -> SyscallResult<(E0, E1, E2)> { - let e0 = E0Store::read_at_offset(address_domain, base, offset)?; - offset += E0Store::size(); - let e1 = E1Store::read_at_offset(address_domain, base, offset)?; - offset += E1Store::size(); - let e2 = E2Store::read_at_offset(address_domain, base, offset)?; - Result::Ok((e0, e1, e2)) - } - #[inline(always)] - fn write_at_offset( - address_domain: u32, base: StorageBaseAddress, mut offset: u8, value: (E0, E1, E2) - ) -> SyscallResult<()> { - let (e0, e1, e2) = value; - E0Store::write_at_offset(address_domain, base, offset, e0)?; - offset += E0Store::size(); - E1Store::write_at_offset(address_domain, base, offset, e1)?; - offset += E1Store::size(); - E2Store::write_at_offset(address_domain, base, offset, e2) - } - #[inline(always)] - fn size() -> u8 { - E0Store::size() + E1Store::size() + E2Store::size() - } -} - -impl TupleSize4Store< - E0, - E1, - E2, - E3, - impl E0Store: Store, - +Drop, - impl E1Store: Store, - +Drop, - impl E2Store: Store, - +Drop, - impl E3Store: Store, - +Drop -> of Store<(E0, E1, E2, E3)> { - #[inline(always)] - fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult<(E0, E1, E2, E3)> { - let e0 = E0Store::read(address_domain, base)?; - let mut offset = E0Store::size(); - let e1 = E1Store::read_at_offset(address_domain, base, offset)?; - offset += E1Store::size(); - let e2 = E2Store::read_at_offset(address_domain, base, offset)?; - offset += E2Store::size(); - let e3 = E3Store::read_at_offset(address_domain, base, offset)?; - Result::Ok((e0, e1, e2, e3)) - } - #[inline(always)] - fn write( - address_domain: u32, base: StorageBaseAddress, value: (E0, E1, E2, E3) - ) -> SyscallResult<()> { - let (e0, e1, e2, e3) = value; - E0Store::write(address_domain, base, e0)?; - let mut offset = E0Store::size(); - E1Store::write_at_offset(address_domain, base, offset, e1)?; - offset += E1Store::size(); - E2Store::write_at_offset(address_domain, base, offset, e2)?; - offset += E2Store::size(); - E3Store::write_at_offset(address_domain, base, offset, e3) - } - #[inline(always)] - fn read_at_offset( - address_domain: u32, base: StorageBaseAddress, mut offset: u8 - ) -> SyscallResult<(E0, E1, E2, E3)> { - let e0 = E0Store::read_at_offset(address_domain, base, offset)?; - offset += E0Store::size(); - let e1 = E1Store::read_at_offset(address_domain, base, offset)?; - offset += E1Store::size(); - let e2 = E2Store::read_at_offset(address_domain, base, offset)?; - offset += E2Store::size(); - let e3 = E3Store::read_at_offset(address_domain, base, offset)?; - Result::Ok((e0, e1, e2, e3)) - } - #[inline(always)] - fn write_at_offset( - address_domain: u32, base: StorageBaseAddress, mut offset: u8, value: (E0, E1, E2, E3) - ) -> SyscallResult<()> { - let (e0, e1, e2, e3) = value; - E0Store::write_at_offset(address_domain, base, offset, e0)?; - offset += E0Store::size(); - E1Store::write_at_offset(address_domain, base, offset, e1)?; - offset += E1Store::size(); - E2Store::write_at_offset(address_domain, base, offset, e2)?; - offset += E2Store::size(); - E3Store::write_at_offset(address_domain, base, offset, e3) - } - #[inline(always)] - fn size() -> u8 { - E0Store::size() + E1Store::size() + E2Store::size() + E3Store::size() - } -} - -impl ResultStore, +Store, +Drop, +Drop> of Store> { - #[inline(always)] - fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult> { - let idx = Store::::read(address_domain, base)?; - if idx == 0 { - starknet::SyscallResult::Ok( - Result::Ok(Store::read_at_offset(address_domain, base, 1_u8)?) - ) - } else if idx == 1 { - starknet::SyscallResult::Ok( - Result::Err(Store::read_at_offset(address_domain, base, 1_u8)?) - ) - } else { - starknet::SyscallResult::Err(array!['Incorrect index:']) - } - } - #[inline(always)] - fn write( - address_domain: u32, base: StorageBaseAddress, value: Result - ) -> SyscallResult<()> { - match value { - Result::Ok(x) => { - Store::write(address_domain, base, 0)?; - Store::write_at_offset(address_domain, base, 1_u8, x)?; - }, - Result::Err(x) => { - Store::write(address_domain, base, 1)?; - Store::write_at_offset(address_domain, base, 1_u8, x)?; - } - }; - starknet::SyscallResult::Ok(()) - } - #[inline(always)] - fn read_at_offset( - address_domain: u32, base: StorageBaseAddress, offset: u8 - ) -> SyscallResult> { - let idx = Store::::read_at_offset(address_domain, base, offset)?; - if idx == 0 { - starknet::SyscallResult::Ok( - Result::Ok(Store::read_at_offset(address_domain, base, offset + 1_u8)?) - ) - } else if idx == 1 { - starknet::SyscallResult::Ok( - Result::Err(Store::read_at_offset(address_domain, base, offset + 1_u8)?) - ) - } else { - starknet::SyscallResult::Err(array!['Incorrect index:']) - } - } - #[inline(always)] - fn write_at_offset( - address_domain: u32, base: StorageBaseAddress, offset: u8, value: Result - ) -> SyscallResult<()> { - match value { - Result::Ok(x) => { - Store::write(address_domain, base, 0)?; - Store::write_at_offset(address_domain, base, 1_u8, x)?; - }, - Result::Err(x) => { - Store::write(address_domain, base, 1)?; - Store::write_at_offset(address_domain, base, 1_u8, x)?; - } - }; - starknet::SyscallResult::Ok(()) - } - #[inline(always)] - fn size() -> u8 { - 1 + core::cmp::max(Store::::size(), Store::::size()) - } -} - -impl OptionStore, +Drop,> of Store> { - #[inline(always)] - fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult> { - let idx = Store::::read(address_domain, base)?; - if idx == 1 { - starknet::SyscallResult::Ok( - Option::Some(Store::read_at_offset(address_domain, base, 1_u8)?) - ) - } else if idx == 0 { - starknet::SyscallResult::Ok(Option::None) - } else { - starknet::SyscallResult::Err(array!['Incorrect index:']) - } - } - #[inline(always)] - fn write(address_domain: u32, base: StorageBaseAddress, value: Option) -> SyscallResult<()> { - match value { - Option::Some(x) => { - Store::write(address_domain, base, 1)?; - Store::write_at_offset(address_domain, base, 1_u8, x)?; - }, - Option::None(_) => { Store::write(address_domain, base, 0)?; } - }; - starknet::SyscallResult::Ok(()) - } - #[inline(always)] - fn read_at_offset( - address_domain: u32, base: StorageBaseAddress, offset: u8 - ) -> SyscallResult> { - let idx = Store::::read_at_offset(address_domain, base, offset)?; - if idx == 1 { - starknet::SyscallResult::Ok( - Option::Some(Store::read_at_offset(address_domain, base, offset + 1_u8)?) - ) - } else if idx == 0 { - starknet::SyscallResult::Ok(Option::None) - } else { - starknet::SyscallResult::Err(array!['Incorrect index:']) - } - } - #[inline(always)] - fn write_at_offset( - address_domain: u32, base: StorageBaseAddress, offset: u8, value: Option - ) -> SyscallResult<()> { - match value { - Option::Some(x) => { - Store::write(address_domain, base, 1)?; - Store::write_at_offset(address_domain, base, 1_u8, x)?; - }, - Option::None(_x) => { Store::write(address_domain, base, 0)?; } - }; - starknet::SyscallResult::Ok(()) - } - #[inline(always)] - fn size() -> u8 { - 1 + Store::::size() - } -} - -/// Store for a `ByteArray`. -/// -/// The layout of a `ByteArray` in storage is as follows: -/// * Only the length in bytes is stored in the original address where the byte array is logically -/// stored. -/// * The actual data is stored in chunks of 256 `bytes31`s in another place in storage -/// determined by the hash of: -/// - The address storing the length of the array. -/// - The chunk index. -/// - The short string `ByteArray`. -impl ByteArrayStore of Store { - #[inline(always)] - fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult { - inner_read_byte_array(address_domain, storage_address_from_base(base)) - } - #[inline(always)] - fn write(address_domain: u32, base: StorageBaseAddress, value: ByteArray) -> SyscallResult<()> { - inner_write_byte_array(address_domain, storage_address_from_base(base), value) - } - #[inline(always)] - fn read_at_offset( - address_domain: u32, base: StorageBaseAddress, offset: u8 - ) -> SyscallResult { - inner_read_byte_array(address_domain, storage_address_from_base_and_offset(base, offset)) - } - #[inline(always)] - fn write_at_offset( - address_domain: u32, base: StorageBaseAddress, offset: u8, value: ByteArray - ) -> SyscallResult<()> { - inner_write_byte_array( - address_domain, storage_address_from_base_and_offset(base, offset), value - ) - } - #[inline(always)] - fn size() -> u8 { - 1 - } -} - -/// Returns a pointer to the `chunk`'th chunk of the byte array at `address`. -/// The pointer is the `Poseidon` hash of: -/// * `address` - The address of the ByteArray (where the length is stored). -/// * `chunk` - The index of the chunk. -/// * The short string `ByteArray` is used as the capacity argument of the sponge construction -/// (domain separation). -fn inner_byte_array_pointer(address: StorageAddress, chunk: felt252) -> StorageBaseAddress { - let (r, _, _) = core::poseidon::hades_permutation(address.into(), chunk, 'ByteArray'_felt252); - storage_base_address_from_felt252(r) -} - -/// Reads a byte array from storage from domain `address_domain` and address `address`. -/// The length of the byte array is read from `address` at domain `address_domain`. -/// For more info read the documentation of `ByteArrayStore`. -fn inner_read_byte_array(address_domain: u32, address: StorageAddress) -> SyscallResult { - let len: usize = - match starknet::syscalls::storage_read_syscall(address_domain, address)?.try_into() { - Option::Some(x) => x, - Option::None => { return SyscallResult::Err(array!['Invalid ByteArray length']); }, - }; - let (mut remaining_full_words, pending_word_len) = core::DivRem::div_rem( - len, BYTES_IN_BYTES31.try_into().unwrap() - ); - let mut chunk = 0; - let mut chunk_base = inner_byte_array_pointer(address, chunk); - let mut index_in_chunk = 0_u8; - let mut result: ByteArray = Default::default(); - loop { - if remaining_full_words == 0 { - break Result::Ok(()); - } - let value = - match starknet::syscalls::storage_read_syscall( - address_domain, storage_address_from_base_and_offset(chunk_base, index_in_chunk) - ) { - Result::Ok(value) => value, - Result::Err(err) => { break Result::Err(err); }, - }; - let value: bytes31 = match value.try_into() { - Option::Some(x) => x, - Option::None => { break Result::Err(array!['Invalid value']); }, - }; - result.data.append(value); - remaining_full_words -= 1; - index_in_chunk = match core::integer::u8_overflowing_add(index_in_chunk, 1) { - Result::Ok(x) => x, - Result::Err(_) => { - // After reading 256 `bytes31`s `index_in_chunk` will overflow and we move to the - // next chunk. - chunk += 1; - chunk_base = inner_byte_array_pointer(address, chunk); - 0 - }, - }; - }?; - if pending_word_len != 0 { - let pending_word = starknet::syscalls::storage_read_syscall( - address_domain, storage_address_from_base_and_offset(chunk_base, index_in_chunk) - )?; - result.pending_word = pending_word; - result.pending_word_len = pending_word_len; - } - Result::Ok(result) -} - -/// Writes a byte array to storage to domain `address_domain` and address `address`. -/// The length of the byte array is written to `address` at domain `address_domain`. -/// For more info read the documentation of `ByteArrayStore`. -fn inner_write_byte_array( - address_domain: u32, address: StorageAddress, value: ByteArray -) -> SyscallResult<()> { - let len = value.len(); - starknet::syscalls::storage_write_syscall(address_domain, address, len.into())?; - let mut full_words = value.data.span(); - let mut chunk = 0; - let mut chunk_base = inner_byte_array_pointer(address, chunk); - let mut index_in_chunk = 0_u8; - loop { - let curr_value = match full_words.pop_front() { - Option::Some(x) => x, - Option::None => { break Result::Ok(()); }, - }; - match starknet::syscalls::storage_write_syscall( - address_domain, - storage_address_from_base_and_offset(chunk_base, index_in_chunk), - (*curr_value).into() - ) { - Result::Ok(_) => {}, - Result::Err(err) => { break Result::Err(err); }, - }; - index_in_chunk = match core::integer::u8_overflowing_add(index_in_chunk, 1) { - Result::Ok(x) => x, - Result::Err(_) => { - // After writing 256 `byte31`s `index_in_chunk` will overflow and we move to the - // next chunk. - chunk += 1; - chunk_base = inner_byte_array_pointer(address, chunk); - 0 - }, - }; - }?; - if value.pending_word_len != 0 { - starknet::syscalls::storage_write_syscall( - address_domain, - storage_address_from_base_and_offset(chunk_base, index_in_chunk), - value.pending_word - )?; - } - Result::Ok(()) -} diff --git a/corelib/src/starknet/syscalls.cairo b/corelib/src/starknet/syscalls.cairo deleted file mode 100644 index bf785a90f..000000000 --- a/corelib/src/starknet/syscalls.cairo +++ /dev/null @@ -1,99 +0,0 @@ -use starknet::{ - SyscallResult, storage_access::StorageAddress, class_hash::ClassHash, - contract_address::ContractAddress -}; - -// Calls a given contract. -// `address` - The address of the called contract. -// `entry_point_selector` - A selector for a function within that contract. -// `calldata` - Call arguments. -pub extern fn call_contract_syscall( - address: ContractAddress, entry_point_selector: felt252, calldata: Span -) -> SyscallResult> implicits(GasBuiltin, System) nopanic; - -// Deploys a new instance of a previously declared class. -// `class_hash` - The class hash of the contract to be deployed. -// `contract_address_salt` - The salt, an arbitrary value provided by the sender, used in the -// computation of the contract's address. -// `calldata` - Call arguments for the constructor. -// `deploy_from_zero` - Deploy the contract from the zero address. -// -// Returns the address of the deployed contract and the serialized return value of the constructor. -pub extern fn deploy_syscall( - class_hash: ClassHash, - contract_address_salt: felt252, - calldata: Span, - deploy_from_zero: bool, -) -> SyscallResult<(ContractAddress, Span)> implicits(GasBuiltin, System) nopanic; - -// Emits an event. -// `keys` - The keys of the event. -// `data` - The data of the event. -pub extern fn emit_event_syscall( - keys: Span, data: Span -) -> SyscallResult<()> implicits(GasBuiltin, System) nopanic; - -// Gets the block hash of the block with the given number. -pub extern fn get_block_hash_syscall( - block_number: u64 -) -> SyscallResult implicits(GasBuiltin, System) nopanic; - -// Gets information about the current execution. -pub extern fn get_execution_info_syscall() -> SyscallResult< - Box -> implicits(GasBuiltin, System) nopanic; - -// Gets information about the current execution, version 2. -pub extern fn get_execution_info_v2_syscall() -> SyscallResult< - Box -> implicits(GasBuiltin, System) nopanic; - -// Calls the requested function in any previously declared class. -// `class_hash` - The hash of the class you want to use. -// `function_selector` - A selector for a function within that class. -// `calldata` - Call arguments. -pub extern fn library_call_syscall( - class_hash: ClassHash, function_selector: felt252, calldata: Span -) -> SyscallResult> implicits(GasBuiltin, System) nopanic; - -// TODO(Ilya): Decide if we limit the type of `to_address`. -// Sends a message to L1. -// `to_address` - The recipient's L1 address. -// `payload` - The content of the message. -pub extern fn send_message_to_l1_syscall( - to_address: felt252, payload: Span -) -> SyscallResult<()> implicits(GasBuiltin, System) nopanic; - -// Gets the value of a key in the storage of the calling contract. -// `address_domain` - The domain of the address. Only address_domain 0 is currently supported, -// in the future it will enable access to address spaces with different data availability -// guarantees. -// `address` - The address of the storage key to read. -pub extern fn storage_read_syscall( - address_domain: u32, address: StorageAddress, -) -> SyscallResult implicits(GasBuiltin, System) nopanic; - -// Sets the value of a key in the storage of the calling contract. -// `address_domain` - The domain of the address. Only address_domain 0 is currently supported, -// in the future it will enable access to address spaces with different data availability -// guarantees. -// `address` - The address of the storage key to write. -// `value` - The value to write to the key. -pub extern fn storage_write_syscall( - address_domain: u32, address: StorageAddress, value: felt252 -) -> SyscallResult<()> implicits(GasBuiltin, System) nopanic; - - -// Replaces the class hash of the current contract. -// `class_hash` - The class hash that should replace the current one. -pub extern fn replace_class_syscall( - class_hash: ClassHash -) -> SyscallResult<()> implicits(GasBuiltin, System) nopanic; - - -// Computes the keccak of the input. -// The system call does not add any padding and the input needs to be a multiple of 1088 bits -// (== 17 u64 word). -pub extern fn keccak_syscall( - input: Span -) -> SyscallResult implicits(GasBuiltin, System) nopanic; diff --git a/corelib/src/starknet/testing.cairo b/corelib/src/starknet/testing.cairo deleted file mode 100644 index 68258b0a7..000000000 --- a/corelib/src/starknet/testing.cairo +++ /dev/null @@ -1,92 +0,0 @@ -use starknet::ContractAddress; -use core::array::ArrayTrait; -use core::array::SpanTrait; -use core::traits::Into; - -// A general cheatcode function used to simplify implementation of Starknet testing functions. -// External users of the cairo crates can also implement their own cheatcodes -// by injecting custom `CairoHintProcessor`. -pub extern fn cheatcode( - input: Span -) -> Span implicits() nopanic; - -// Set the block number to the provided value. -pub fn set_block_number(block_number: u64) { - cheatcode::<'set_block_number'>(array![block_number.into()].span()); -} - -// Set the caller address to the provided value. -pub fn set_caller_address(address: ContractAddress) { - cheatcode::<'set_caller_address'>(array![address.into()].span()); -} - -// Set the contract address to the provided value. -pub fn set_contract_address(address: ContractAddress) { - cheatcode::<'set_contract_address'>(array![address.into()].span()); -} - -// Set the sequencer address to the provided value. -pub fn set_sequencer_address(address: ContractAddress) { - cheatcode::<'set_sequencer_address'>(array![address.into()].span()); -} - -// Set the block timestamp to the provided value. -pub fn set_block_timestamp(block_timestamp: u64) { - cheatcode::<'set_block_timestamp'>(array![block_timestamp.into()].span()); -} - -// Set the version to the provided value. -pub fn set_version(version: felt252) { - cheatcode::<'set_version'>(array![version].span()); -} - -// Set the account contract address. -pub fn set_account_contract_address(address: ContractAddress) { - cheatcode::<'set_account_contract_address'>(array![address.into()].span()); -} - -// Set the max fee. -pub fn set_max_fee(fee: u128) { - cheatcode::<'set_max_fee'>(array![fee.into()].span()); -} - -// Set the transaction hash. -pub fn set_transaction_hash(hash: felt252) { - cheatcode::<'set_transaction_hash'>(array![hash].span()); -} - -// Set the chain id. -pub fn set_chain_id(chain_id: felt252) { - cheatcode::<'set_chain_id'>(array![chain_id].span()); -} - -// Set the nonce. -pub fn set_nonce(nonce: felt252) { - cheatcode::<'set_nonce'>(array![nonce].span()); -} - -// Set the signature. -pub fn set_signature(signature: Span) { - cheatcode::<'set_signature'>(signature); -} - -// Pop the earliest unpopped logged event for the contract. -pub fn pop_log_raw(address: ContractAddress) -> Option<(Span, Span)> { - let mut log = cheatcode::<'pop_log'>(array![address.into()].span()); - Option::Some((Serde::deserialize(ref log)?, Serde::deserialize(ref log)?,)) -} - -// Pop the earliest unpopped logged event for the contract as the requested type. -pub fn pop_log>(address: ContractAddress) -> Option { - let (mut keys, mut data) = pop_log_raw(address)?; - starknet::Event::deserialize(ref keys, ref data) -} - -// TODO(Ilya): Decide if we limit the type of `to_address`. -// Pop the earliest unpopped l2 to l1 message for the contract. -pub fn pop_l2_to_l1_message(address: ContractAddress) -> Option<(felt252, Span)> { - let mut l2_to_l1_message = cheatcode::<'pop_l2_to_l1_message'>(array![address.into()].span()); - Option::Some( - (Serde::deserialize(ref l2_to_l1_message)?, Serde::deserialize(ref l2_to_l1_message)?,) - ) -} diff --git a/corelib/src/string.cairo b/corelib/src/string.cairo deleted file mode 100644 index 7368771d2..000000000 --- a/corelib/src/string.cairo +++ /dev/null @@ -1 +0,0 @@ -pub trait StringLiteral; diff --git a/corelib/src/test.cairo b/corelib/src/test.cairo deleted file mode 100644 index d227ed15d..000000000 --- a/corelib/src/test.cairo +++ /dev/null @@ -1,28 +0,0 @@ -mod array_test; -mod bool_test; -mod box_test; -mod byte_array_test; -mod bytes31_test; -mod cmp_test; -mod const_test; -mod coupon_test; -mod dict_test; -mod ec_test; -mod felt_test; -mod fmt_test; -mod hash_test; -mod integer_test; -mod keccak_test; -mod num_test; -mod math_test; -mod nullable_test; -mod panics_test; -mod plugins_test; -mod print_test; -mod result_test; -mod secp256k1_test; -mod secp256r1_test; -mod test_utils; -mod testing_test; -mod to_byte_array_test; -mod while_test; diff --git a/corelib/src/test/array_test.cairo b/corelib/src/test/array_test.cairo deleted file mode 100644 index 3f002c2e4..000000000 --- a/corelib/src/test/array_test.cairo +++ /dev/null @@ -1,154 +0,0 @@ -use core::test::test_utils::{assert_eq, assert_ne}; - -#[test] -fn test_array() { - let arr = array![10, 11, 12]; - assert_eq(arr[0], @10, 'array[0] != 10'); - assert_eq(arr[1], @11, 'array[1] != 11'); - assert_eq(arr[2], @12, 'array[2] != 12'); -} - -#[test] -#[should_panic] -fn test_array_out_of_bound_1() { - let arr = array![10, 11, 12]; - arr[3]; -} - -#[test] -#[should_panic] -fn test_array_out_of_bound_2() { - let arr = array![10, 11, 12]; - arr[11]; -} - -#[test] -fn test_array_clone() { - let felt252_snap_array: @Array = @array![10, 11, 12]; - let felt252_snap_array_clone = felt252_snap_array.clone(); - assert_eq(@felt252_snap_array_clone.len(), @3, 'array len != 3'); - assert_eq(felt252_snap_array_clone[0], @10, 'array[0] != 10'); - assert_eq(felt252_snap_array_clone[1], @11, 'array[1] != 11'); - assert_eq(felt252_snap_array_clone[2], @12, 'array[2] != 12'); -} - -#[test] -fn test_span() { - let mut span = array![10, 11, 12].span(); - assert_eq(@span.len(), @3, 'Unexpected span length.'); - assert_eq(span.get(0).unwrap().unbox(), @10, 'Unexpected element'); - assert_eq(span.pop_front().unwrap(), @10, 'Unexpected element'); - assert_eq(@span.len(), @2, 'Unexpected span length.'); - assert_eq(span[1], @12, 'Unexpected element'); - assert_eq(span.pop_back().unwrap(), @12, 'Unexpected element'); - assert_eq(@span.len(), @1, 'Unexpected span length.'); -} - -#[test] -fn test_slice() { - let span = array![10, 11, 12].span(); - assert_eq(@span.slice(0, 3).len(), @3, 'Unexpected span length.'); - assert_eq(span.slice(0, 3)[0], @10, 'Unexpected Element.'); - assert_eq(@span.slice(0, 2).len(), @2, 'Unexpected span length.'); - assert_eq(span.slice(0, 2)[0], @10, 'Unexpected Element.'); - assert_eq(@span.slice(0, 1).len(), @1, 'Unexpected span length.'); - assert_eq(span.slice(0, 1)[0], @10, 'Unexpected Element.'); - assert_eq(@span.slice(0, 0).len(), @0, 'Unexpected span length.'); - assert_eq(@span.slice(1, 2).len(), @2, 'Unexpected span length.'); - assert_eq(span.slice(1, 2)[0], @11, 'Unexpected Element.'); - assert_eq(@span.slice(1, 1).len(), @1, 'Unexpected span length.'); - assert_eq(span.slice(1, 1)[0], @11, 'Unexpected Element.'); - assert_eq(@span.slice(1, 0).len(), @0, 'Unexpected span length.'); -} - -#[test] -#[should_panic] -fn test_slice_out_of_bound_1() { - array![10, 11, 12].span().slice(3, 1); -} - -#[test] -#[should_panic] -fn test_slice_out_of_bound_2() { - array![10, 11, 12].span().slice(0, 4); -} - -#[test] -fn test_equality() { - let arr1 = array![]; - let arr2 = array![10, 11, 12]; - let arr3 = array![10, 11, 13]; - let arr4 = array![10, 11]; - let arr5 = array![10, 11, 12, 13]; - - assert(arr1 == arr1, 'arr1 != arr1'); - assert(arr2 == arr2, 'arr2 != arr2'); - assert(arr3 == arr3, 'arr3 != arr3'); - assert(arr4 == arr4, 'arr4 != arr4'); - assert(arr5 == arr5, 'arr5 != arr5'); - - assert(arr1 != arr2, 'arr1 == arr2'); - assert(arr1 != arr3, 'arr1 == arr3'); - assert(arr1 != arr4, 'arr1 == arr4'); - assert(arr1 != arr5, 'arr1 == arr5'); - assert(arr2 != arr3, 'arr2 == arr3'); - assert(arr2 != arr4, 'arr2 == arr4'); - assert(arr2 != arr5, 'arr2 == arr5'); - assert(arr3 != arr4, 'arr3 == arr4'); - assert(arr3 != arr5, 'arr3 == arr5'); - assert(arr4 != arr5, 'arr4 == arr5'); -} - -#[test] -fn test_append() { - let mut arr = array![10, 11, 12]; - arr.append(13); - assert(arr.len() == 4, 'Unexpected length'); - assert_eq(arr[3], @13, 'Unexpected element'); -} - -#[test] -fn test_append_span() { - let mut arr = array![10, 11, 12]; - arr.append_span(arr.span()); - assert(arr.len() == 6, 'Unexpected length'); - assert_eq(arr[3], @10, 'Unexpected element'); - assert_eq(arr[4], @11, 'Unexpected element'); - assert_eq(arr[5], @12, 'Unexpected element'); -} - -mod felt252_span_from_tuple { - pub extern fn span_from_tuple(struct_like: Box<@T>) -> @Array nopanic; -} - -mod tuple_span_from_tuple { - pub extern fn span_from_tuple( - struct_like: Box<@T> - ) -> @Array<(felt252, felt252, felt252)> nopanic; -} - -#[test] -fn test_felt252_span_from_tuple() { - let span = felt252_span_from_tuple::span_from_tuple(BoxTrait::new(@(10, 20, 30))); - assert!(*span[0] == 10); - assert!(*span[1] == 20); - assert!(*span[2] == 30); -} - -#[test] -fn test_tuple_span_from_tuple() { - let multi_tuple = ((10, 20, 30), (40, 50, 60), (70, 80, 90)); - let span = tuple_span_from_tuple::span_from_tuple(BoxTrait::new(@multi_tuple)); - assert!(*span[0] == (10, 20, 30)); - assert!(*span[1] == (40, 50, 60)); - assert!(*span[2] == (70, 80, 90)); -} - -#[test] -fn test_fixed_size_array() { - let arr = [10, 11, 12]; - let [x, y, z] = arr; - assert_eq!(x, 10); - assert_eq!(y, 11); - assert_eq!(z, 12); -} diff --git a/corelib/src/test/bool_test.cairo b/corelib/src/test/bool_test.cairo deleted file mode 100644 index 9cab5d677..000000000 --- a/corelib/src/test/bool_test.cairo +++ /dev/null @@ -1,29 +0,0 @@ -use core::test::test_utils::{assert_eq, assert_ne}; - -#[test] -fn test_bool_operators() { - assert_eq(@true, @true, 't != t'); - assert_eq(@false, @false, 'f != f'); - assert_eq(@!true, @false, '!t != f'); - assert_eq(@!false, @true, '!f != t'); - assert_ne(@true, @false, 't == f'); - assert_ne(@false, @true, 'f == t'); - assert(!(false & false), '!(f & f)'); - assert(!(true & false), '!(t & f)'); - assert(!(false & true), '!(f & t)'); - assert(true & true, 't & t'); - assert(!(false | false), '!(f | f)'); - assert(true | false, 't | f'); - assert(false | true, 'f | t'); - assert(true | true, 't | t'); - assert(!(false ^ false), '!(f ^ f)'); - assert(true ^ false, 't ^ f'); - assert(false ^ true, 'f ^ t'); - assert(!(true ^ true), '!(t ^ t)'); -} - -#[test] -fn test_bool_conversion() { - assert_eq(@false.into(), @0, 'f.into() != 0'); - assert_eq(@true.into(), @1, 'f.into() != 1'); -} diff --git a/corelib/src/test/box_test.cairo b/corelib/src/test/box_test.cairo deleted file mode 100644 index d703e65ef..000000000 --- a/corelib/src/test/box_test.cairo +++ /dev/null @@ -1,22 +0,0 @@ -use core::test::test_utils::{assert_eq, assert_ne}; - -#[test] -fn test_box_unbox_felt252s() { - let x = 10; - let boxed_x = BoxTrait::new(x); - let y = 11; - let boxed_y = BoxTrait::new(y); - assert_eq(@boxed_x.unbox(), @10, 'x != 10'); - assert_eq(@boxed_y.unbox(), @11, 'y != 11'); -} - -// Test objects of size>1. -#[test] -fn test_box_unbox_u256() { - let x = u256 { low: 1, high: 0 }; - let boxed_x = BoxTrait::new(x); - let y = u256 { low: 1, high: 1 }; - let boxed_y = BoxTrait::new(y); - assert_eq(@boxed_x.unbox(), @x, 'unbox u256 x'); - assert_eq(@boxed_y.unbox(), @y, 'unbox u256 y'); -} diff --git a/corelib/src/test/byte_array_test.cairo b/corelib/src/test/byte_array_test.cairo deleted file mode 100644 index dd62b66f4..000000000 --- a/corelib/src/test/byte_array_test.cairo +++ /dev/null @@ -1,568 +0,0 @@ -use core::test::test_utils::{assert_eq, assert_ne}; - -#[test] -fn test_append_byte() { - let mut ba = Default::default(); - let mut c = 1_u8; - loop { - if c == 34 { - break; - } - ba.append_byte(c); - c += 1; - }; - - let expected_data = array![0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f]; - compare_byte_array(@ba, expected_data.span(), 2, 0x2021); -} - -#[test] -fn test_append_word() { - let mut ba = Default::default(); - - ba.append_word(0x0102030405060708091a0b0c0d0e0f101112131415161718191a1b1c1d1e, 30); - compare_byte_array( - @ba, array![].span(), 30, 0x0102030405060708091a0b0c0d0e0f101112131415161718191a1b1c1d1e - ); - - ba.append_word(0x1f2021, 3); - let expected_data = array![0x0102030405060708091a0b0c0d0e0f101112131415161718191a1b1c1d1e1f]; - compare_byte_array(@ba, expected_data.span(), 2, 0x2021); - - ba.append_word(0x2223, 2); - compare_byte_array(@ba, expected_data.span(), 4, 0x20212223); - - // Length is 0, so nothing is actually appended. - ba.append_word(0xffee, 0); - compare_byte_array(@ba, expected_data.span(), 4, 0x20212223); - - ba.append_word(0x2425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e, 27); - let expected_data = array![ - 0x0102030405060708091a0b0c0d0e0f101112131415161718191a1b1c1d1e1f, - 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e - ]; - compare_byte_array(@ba, expected_data.span(), 0, 0); - - ba.append_word(0x3f, 1); - compare_byte_array(@ba, expected_data.span(), 1, 0x3f); -} - -#[test] -fn test_append() { - let mut ba1 = test_byte_array_32(); - let ba2 = test_byte_array_32(); - - ba1.append(@ba2); - - let expected_data = array![ - 0x0102030405060708091a0b0c0d0e0f101112131415161718191a1b1c1d1e1f, - 0x200102030405060708091a0b0c0d0e0f101112131415161718191a1b1c1d1e - ]; - compare_byte_array(@ba1, expected_data.span(), 2, 0x1f20); -} - -// Same as test_append, but with `+=` instead of `append`. -#[test] -fn test_add_eq() { - let mut ba1 = test_byte_array_32(); - let ba2 = test_byte_array_32(); - - ba1 += ba2; - - let expected_data = array![ - 0x0102030405060708091a0b0c0d0e0f101112131415161718191a1b1c1d1e1f, - 0x200102030405060708091a0b0c0d0e0f101112131415161718191a1b1c1d1e - ]; - compare_byte_array(@ba1, expected_data.span(), 2, 0x1f20); -} - -#[test] -fn test_concat() { - let ba1 = test_byte_array_32(); - let ba2 = test_byte_array_32(); - - let ba3 = ByteArrayTrait::concat(@ba1, @ba2); - - let expected_data = array![ - 0x0102030405060708091a0b0c0d0e0f101112131415161718191a1b1c1d1e1f, - 0x200102030405060708091a0b0c0d0e0f101112131415161718191a1b1c1d1e - ]; - compare_byte_array(@ba3, expected_data.span(), 2, 0x1f20); -} - -// Same as test_concat, but with `+` instead of `concat`. -#[test] -fn test_add() { - let ba1 = test_byte_array_32(); - let ba2 = test_byte_array_32(); - - let ba3 = ba1 + ba2; - - let expected_data = array![ - 0x0102030405060708091a0b0c0d0e0f101112131415161718191a1b1c1d1e1f, - 0x200102030405060708091a0b0c0d0e0f101112131415161718191a1b1c1d1e - ]; - compare_byte_array(@ba3, expected_data.span(), 2, 0x1f20); -} - -// Test concat/append, first byte array empty. -#[test] -fn test_concat_first_empty() { - let ba1 = Default::default(); - let ba2 = test_byte_array_32(); - - let ba3 = ByteArrayTrait::concat(@ba1, @ba2); - - let expected_data = array![0x0102030405060708091a0b0c0d0e0f101112131415161718191a1b1c1d1e1f]; - compare_byte_array(@ba3, expected_data.span(), 1, 0x20); -} - -// Test concat/append, second byte array empty. -#[test] -fn test_concat_second_empty() { - let ba1 = test_byte_array_32(); - let ba2 = Default::default(); - - let ba3 = ByteArrayTrait::concat(@ba1, @ba2); - - let expected_data = array![0x0102030405060708091a0b0c0d0e0f101112131415161718191a1b1c1d1e1f]; - compare_byte_array(@ba3, expected_data.span(), 1, 0x20); -} - -// Test concat/append, first byte array pending word is empty. -#[test] -fn test_concat_first_pending_0() { - let ba1 = test_byte_array_31(); - let ba2 = test_byte_array_32(); - - let ba3 = ByteArrayTrait::concat(@ba1, @ba2); - - let expected_data = array![ - 0x0102030405060708091a0b0c0d0e0f101112131415161718191a1b1c1d1e1f, - 0x0102030405060708091a0b0c0d0e0f101112131415161718191a1b1c1d1e1f - ]; - compare_byte_array(@ba3, expected_data.span(), 1, 0x20); -} - -// Test concat/append, second byte array pending word is empty. -#[test] -fn test_concat_second_pending_0() { - let ba1 = test_byte_array_32(); - let ba2 = test_byte_array_31(); - - let ba3 = ByteArrayTrait::concat(@ba1, @ba2); - - let expected_data = array![ - 0x0102030405060708091a0b0c0d0e0f101112131415161718191a1b1c1d1e1f, - 0x200102030405060708091a0b0c0d0e0f101112131415161718191a1b1c1d1e - ]; - compare_byte_array(@ba3, expected_data.span(), 1, 0x1f); -} - -// Test concat/append, split index of the words of the second byte array is 16. -#[test] -fn test_concat_split_index_16() { - let ba1 = test_byte_array_16(); - let ba2 = test_byte_array_32(); - - let ba3 = ByteArrayTrait::concat(@ba1, @ba2); - - let expected_data = array![0x0102030405060708091a0b0c0d0e0f100102030405060708091a0b0c0d0e0f]; - compare_byte_array(@ba3, expected_data.span(), 17, 0x101112131415161718191a1b1c1d1e1f20); -} - -// Test concat/append, split index of the words of the second byte array is < 16, specifically 1. -#[test] -fn test_concat_split_index_lt_16() { - let ba1 = test_byte_array_1(); - let ba2 = test_byte_array_32(); - - let ba3 = ByteArrayTrait::concat(@ba1, @ba2); - - let expected_data = array![0x010102030405060708091a0b0c0d0e0f101112131415161718191a1b1c1d1e]; - compare_byte_array(@ba3, expected_data.span(), 2, 0x1f20); -} - -// Test concat/append, split index of the words of the second byte array is > 16, specifically 30. -#[test] -fn test_concat_split_index_gt_16() { - let ba1 = test_byte_array_30(); - let ba2 = test_byte_array_33(); - - let ba3 = ByteArrayTrait::concat(@ba1, @ba2); - - let expected_data = array![ - 0x0102030405060708091a0b0c0d0e0f101112131415161718191a1b1c1d1e01, - 0x02030405060708091a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 - ]; - compare_byte_array(@ba3, expected_data.span(), 1, 0x21); -} - -// Sum of the lengths of the pending words of both byte arrays is 31 (a full word). -#[test] -fn test_concat_pending_sum_up_to_full() { - let ba1 = test_byte_array_32(); - let ba2 = test_byte_array_30(); - - let ba3 = ByteArrayTrait::concat(@ba1, @ba2); - - let expected_data = array![ - 0x0102030405060708091a0b0c0d0e0f101112131415161718191a1b1c1d1e1f, - 0x200102030405060708091a0b0c0d0e0f101112131415161718191a1b1c1d1e - ]; - compare_byte_array(@ba3, expected_data.span(), 0, 0); -} - -// Sum of the lengths of the pending words of both byte arrays is 31+16. -// That is, the pending words aggregate to a full word, and the last split index is 16. -#[test] -fn test_concat_pending_sum_up_to_more_than_word_16() { - let ba1 = test_byte_array_17(); - let ba2 = test_byte_array_30(); - - let ba3 = ByteArrayTrait::concat(@ba1, @ba2); - - let expected_data = array![0x0102030405060708091a0b0c0d0e0f10110102030405060708091a0b0c0d0e]; - compare_byte_array(@ba3, expected_data.span(), 16, 0x0f101112131415161718191a1b1c1d1e); -} - -// Sum of the lengths of the pending words of both byte arrays is in [32, 31+15]. -// That is, the pending words aggregate to a full word, and the last split index is <16. -#[test] -fn test_concat_pending_sum_up_to_more_than_word_lt16() { - let ba1 = test_byte_array_2(); - let ba2 = test_byte_array_30(); - - let ba3 = ByteArrayTrait::concat(@ba1, @ba2); - - let expected_data = array![0x01020102030405060708091a0b0c0d0e0f101112131415161718191a1b1c1d]; - compare_byte_array(@ba3, expected_data.span(), 1, 0x1e); -} - -// Sum of the lengths of the pending words of both byte arrays is >31+15 -// That is, the pending words aggregate to a full word, and the last split index is >16. -#[test] -fn test_concat_pending_sum_up_to_more_than_word_gt16() { - let ba1 = test_byte_array_30(); - let ba2 = test_byte_array_30(); - - let ba3 = ByteArrayTrait::concat(@ba1, @ba2); - - let expected_data = array![0x0102030405060708091a0b0c0d0e0f101112131415161718191a1b1c1d1e01]; - compare_byte_array( - @ba3, expected_data.span(), 29, 0x02030405060708091a0b0c0d0e0f101112131415161718191a1b1c1d1e - ); -} - -#[test] -fn test_len() { - let ba: ByteArray = Default::default(); - assert(ba.len() == 0, 'wrong ByteArray len'); - - let mut ba = test_byte_array_33(); - assert(ba.len() == 33, 'wrong ByteArray len'); - - ba.append(@test_byte_array_30()); - assert(ba.len() == 63, 'wrong ByteArray len'); -} - -#[test] -fn test_at_empty() { - let ba: ByteArray = Default::default(); - - assert(ba.at(0) == Option::None, 'index 0 is not out of bounds'); - assert(ba.at(1) == Option::None, 'index 1 is not out of bounds'); - assert(ba.at(30) == Option::None, 'index 30 is not out of bounds'); - assert(ba.at(31) == Option::None, 'index 31 is not out of bounds'); -} - -#[test] -fn test_at() { - let mut ba = test_byte_array_31(); - ba.append(@test_byte_array_31()); - ba.append(@test_byte_array_17()); - - assert(ba.at(0) == Option::Some(0x01), 'wrong byte at index 0'); - assert(ba.at(1) == Option::Some(0x02), 'wrong byte at index 1'); - assert(ba.at(2) == Option::Some(0x03), 'wrong byte at index 2'); - assert(ba.at(14) == Option::Some(0x0f), 'wrong byte at index 14'); - assert(ba.at(15) == Option::Some(0x10), 'wrong byte at index 15'); - assert(ba.at(16) == Option::Some(0x11), 'wrong byte at index 16'); - assert(ba.at(17) == Option::Some(0x12), 'wrong byte at index 17'); - assert(ba.at(29) == Option::Some(0x1e), 'wrong byte at index 29'); - assert(ba.at(30) == Option::Some(0x1f), 'wrong byte at index 30'); - assert(ba.at(31) == Option::Some(0x01), 'wrong byte at index 31'); - assert(ba.at(32) == Option::Some(0x02), 'wrong byte at index 32'); - assert(ba.at(61) == Option::Some(0x1f), 'wrong byte at index 61'); - assert(ba.at(62) == Option::Some(0x01), 'wrong byte at index 62'); - assert(ba.at(63) == Option::Some(0x02), 'wrong byte at index 63'); - assert(ba.at(76) == Option::Some(0x0f), 'wrong byte at index 76'); - assert(ba.at(77) == Option::Some(0x10), 'wrong byte at index 77'); - assert(ba.at(78) == Option::Some(0x11), 'wrong byte at index 78'); - assert(ba.at(79) == Option::None, 'index 79 is not out of bounds'); -} - -// Same as the previous test, but with [] instead of .at() (and without the out-of-bounds case). -#[test] -fn test_index_view() { - let mut ba = test_byte_array_31(); - ba.append(@test_byte_array_31()); - ba.append(@test_byte_array_17()); - - assert(ba[0] == 0x01, 'wrong byte at index 0'); - assert(ba[1] == 0x02, 'wrong byte at index 1'); - assert(ba[2] == 0x03, 'wrong byte at index 2'); - assert(ba[14] == 0x0f, 'wrong byte at index 14'); - assert(ba[15] == 0x10, 'wrong byte at index 15'); - assert(ba[16] == 0x11, 'wrong byte at index 16'); - assert(ba[17] == 0x12, 'wrong byte at index 17'); - assert(ba[29] == 0x1e, 'wrong byte at index 29'); - assert(ba[30] == 0x1f, 'wrong byte at index 30'); - assert(ba[31] == 0x01, 'wrong byte at index 31'); - assert(ba[32] == 0x02, 'wrong byte at index 32'); - assert(ba[61] == 0x1f, 'wrong byte at index 61'); - assert(ba[62] == 0x01, 'wrong byte at index 62'); - assert(ba[63] == 0x02, 'wrong byte at index 63'); - assert(ba[76] == 0x0f, 'wrong byte at index 76'); - assert(ba[77] == 0x10, 'wrong byte at index 77'); - assert(ba[78] == 0x11, 'wrong byte at index 78'); -} - -// Test panic with [] in case of out-of-bounds -#[test] -#[should_panic(expected: ('Index out of bounds',))] -fn test_index_view_out_of_bounds() { - let mut ba = test_byte_array_31(); - ba.append(@test_byte_array_31()); - ba.append(@test_byte_array_17()); - - let _x = ba[79]; -} - -#[test] -fn test_string_literals() { - let _ba: ByteArray = "12345"; // len < 16 - let _ba: ByteArray = "1234567890123456"; // len == 16 - let _ba: ByteArray = "123456789012345678"; // 16 < len < 31 - let _ba: ByteArray = "1234567890123456789012345678901"; // len == 31 - let _ba: ByteArray = "123456789012345678901234567890123"; // 31 < len < 47 - let _ba: ByteArray = "12345678901234567890123456789012345678901234567"; // len == 47 - let _ba: ByteArray = "123456789012345678901234567890123456789012345678"; // len > 47 -} - -#[test] -fn test_equality() { - let byte_array: ByteArray = "a"; - assert(@byte_array == @"a", 'Same strings are not equal'); - assert(@byte_array != @"b", 'Different strings are equal'); - - let mut ba1 = test_byte_array_2(); - ba1.append(@test_byte_array_31()); - let ba2 = test_byte_array_33(); - let ba3 = test_byte_array_32(); - let mut ba4 = test_byte_array_32(); - ba4.append(@test_byte_array_1()); - - assert(@ba1 == @ba1, 'Same ByteArrays are not equal'); - assert(@ba2 == @ba2, 'Same ByteArrays are not equal'); - assert(@ba3 == @ba3, 'Same ByteArrays are not equal'); - assert(@ba4 == @ba4, 'Same ByteArrays are not equal'); - - // Different data - assert(@ba1 != @ba2, 'Different ByteArrays are equal'); - - // Different pending word length - assert(@ba2 != @ba3, 'Different ByteArrays are equal'); - - // Different pending word - assert(@ba2 != @ba4, 'Different ByteArrays are equal'); -} - -#[test] -fn test_reverse() { - // Arrays of length < 16 - let ba: ByteArray = "abc"; - let ba_rev: ByteArray = "cba"; - let palindrome: ByteArray = "rotator"; - assert_ne(@ba, @ba.rev(), 'ba == ba.rev()'); - assert_ne(@ba_rev, @ba_rev.rev(), 'ba_rev == ba_rev.rev()'); - assert_eq(@ba, @ba_rev.rev(), 'ba != ba_rev.rev()'); - assert_eq(@palindrome, @palindrome.rev(), 'palindrome is not a palindrome'); - - // Arrays of length 16 - let ba: ByteArray = "my length is 16."; - let ba_rev: ByteArray = ".61 si htgnel ym"; - let palindrome: ByteArray = "nolemon nomelon"; - assert_ne(@ba, @ba.rev(), 'ba == ba.rev()'); - assert_ne(@ba_rev, @ba_rev.rev(), 'ba_rev == ba_rev.rev()'); - assert_eq(@ba, @ba_rev.rev(), 'ba != ba_rev.rev()'); - assert_eq(@palindrome, @palindrome.rev(), 'palindrome is not a palindrome'); - - // Arrays of 16 < length < 31 - let ba: ByteArray = "I am a medium byte array"; - let ba_rev: ByteArray = "yarra etyb muidem a ma I"; - let palindrome: ByteArray = "nolemon nomelon"; - assert_ne(@ba, @ba.rev(), 'ba == ba.rev()'); - assert_ne(@ba_rev, @ba_rev.rev(), 'ba_rev == ba_rev.rev()'); - assert_eq(@ba, @ba_rev.rev(), 'ba != ba_rev.rev()'); - assert_eq(@palindrome, @palindrome.rev(), 'palindrome is not a palindrome'); - - // Arrays of length 31 - let ba: ByteArray = "I didn't find a good palindrome"; - let ba_rev: ByteArray = "emordnilap doog a dnif t'ndid I"; - let palindrome: ByteArray = "kayak level rotator level kayak"; - assert_ne(@ba, @ba.rev(), 'ba == ba.rev()'); - assert_ne(@ba_rev, @ba_rev.rev(), 'ba_rev == ba_rev.rev()'); - assert_eq(@ba, @ba_rev.rev(), 'ba != ba_rev.rev()'); - assert_eq(@palindrome, @palindrome.rev(), 'palindrome is not a palindrome'); - - // Arrays of 31 < length < 47 (31+16) - let ba: ByteArray = "This time I did find a good palindrome!"; - let ba_rev: ByteArray = "!emordnilap doog a dnif did I emit sihT"; - let palindrome: ByteArray = "noitneverpropagatesifisetagaporprevention"; - assert_ne(@ba, @ba.rev(), 'ba == ba.rev()'); - assert_ne(@ba_rev, @ba_rev.rev(), 'ba_rev == ba_rev.rev()'); - assert_eq(@ba, @ba_rev.rev(), 'ba != ba_rev.rev()'); - assert_eq(@palindrome, @palindrome.rev(), 'palindrome is not a palindrome'); - - // Arrays of length 47 (31+16) - let ba: ByteArray = "I have found a palindrome, exactly 47 in length"; - let ba_rev: ByteArray = "htgnel ni 74 yltcaxe ,emordnilap a dnuof evah I"; - let palindrome: ByteArray = "onacloverifaliveeruptsavastpureevilafirevolcano"; - assert_ne(@ba, @ba.rev(), 'ba == ba.rev()'); - assert_ne(@ba_rev, @ba_rev.rev(), 'ba_rev == ba_rev.rev()'); - assert_eq(@ba, @ba_rev.rev(), 'ba != ba_rev.rev()'); - assert_eq(@palindrome, @palindrome.rev(), 'palindrome is not a palindrome'); - - // Arrays of length > 47 (31+16) - let ba: ByteArray = "This palindrome is not as good, but at least it's long enough"; - let ba_rev: ByteArray = "hguone gnol s'ti tsael ta tub ,doog sa ton si emordnilap sihT"; - let palindrome: ByteArray = "docnoteidissentafastneverpreventsafatnessidietoncod"; - assert_ne(@ba, @ba.rev(), 'ba == ba.rev()'); - assert_ne(@ba_rev, @ba_rev.rev(), 'ba_rev == ba_rev.rev()'); - assert_eq(@ba, @ba_rev.rev(), 'ba != ba_rev.rev()'); - assert_eq(@palindrome, @palindrome.rev(), 'palindrome is not a palindrome'); -} - -#[test] -fn test_serde() { - let mut serialized = array![]; - let ba: ByteArray = ""; - let expected_serialized = array![0, 0, 0]; - ba.serialize(ref serialized); - compare_spans(serialized.span(), expected_serialized.span()); - - let mut serialized = array![]; - let ba: ByteArray = "hello"; - let expected_serialized = array![ - 0, // data len - 0x68656c6c6f, // pending_word - 5 // pending_word_len - ]; - ba.serialize(ref serialized); - compare_spans(serialized.span(), expected_serialized.span()); - - let mut serialized = array![]; - let ba: ByteArray = "Long string, more than 31 characters."; - let expected_serialized = array![ - 1, // data len - 0x4c6f6e6720737472696e672c206d6f7265207468616e203331206368617261, // data - 0x63746572732e, // pending_word - 6 // pending_word_len - ]; - ba.serialize(ref serialized); - compare_spans(serialized.span(), expected_serialized.span()); -} - -// ========= Test helper functions ========= - -fn compare_byte_array( - mut ba: @ByteArray, mut data: Span, pending_word_len: usize, pending_word: felt252 -) { - assert(ba.data.len() == data.len(), 'wrong data len'); - let mut ba_data = ba.data.span(); - - let mut data_index = 0; - loop { - match ba_data.pop_front() { - Option::Some(x) => { - let actual_word = (*x).into(); - let expected_word = *data.pop_front().unwrap(); - assert_eq!(actual_word, expected_word, "wrong data for index: {data_index}"); - }, - Option::None(_) => { break; } - } - data_index += 1; - }; - - assert_eq!(*ba.pending_word_len, pending_word_len); - let ba_pending_word_felt: felt252 = (*ba.pending_word).into(); - assert_eq!(ba_pending_word_felt, pending_word); -} - -fn compare_spans, +PartialEq, +Copy, +Drop>( - mut a: Span, mut b: Span -) { - assert_eq!(a.len(), b.len()); - let mut index = 0; - loop { - match a.pop_front() { - Option::Some(current_a) => { - let current_b = b.pop_front().unwrap(); - assert_eq!(*current_a, *current_b, "wrong data for index: {index}"); - }, - Option::None(_) => { break; } - } - index += 1; - }; -} - -fn test_byte_array_1() -> ByteArray { - let mut ba1 = Default::default(); - ba1.append_word(0x01, 1); - ba1 -} - -fn test_byte_array_2() -> ByteArray { - let mut ba1 = Default::default(); - ba1.append_word(0x0102, 2); - ba1 -} - -fn test_byte_array_16() -> ByteArray { - let mut ba1 = Default::default(); - ba1.append_word(0x0102030405060708091a0b0c0d0e0f10, 16); - ba1 -} - -fn test_byte_array_17() -> ByteArray { - let mut ba1 = Default::default(); - ba1.append_word(0x0102030405060708091a0b0c0d0e0f1011, 17); - ba1 -} - -fn test_byte_array_30() -> ByteArray { - let mut ba1 = Default::default(); - ba1.append_word(0x0102030405060708091a0b0c0d0e0f101112131415161718191a1b1c1d1e, 30); - ba1 -} - -fn test_byte_array_31() -> ByteArray { - let mut ba1 = Default::default(); - ba1.append_word(0x0102030405060708091a0b0c0d0e0f101112131415161718191a1b1c1d1e1f, 31); - ba1 -} - -fn test_byte_array_32() -> ByteArray { - let mut ba1 = Default::default(); - ba1.append_word(0x0102030405060708091a0b0c0d0e0f101112131415161718191a1b1c1d1e1f, 31); - ba1.append_word(0x20, 1); - ba1 -} - -fn test_byte_array_33() -> ByteArray { - let mut ba2 = Default::default(); - ba2.append_word(0x0102030405060708091a0b0c0d0e0f101112131415161718191a1b1c1d1e1f, 31); - ba2.append_word(0x2021, 2); - ba2 -} diff --git a/corelib/src/test/bytes31_test.cairo b/corelib/src/test/bytes31_test.cairo deleted file mode 100644 index 9176c2b56..000000000 --- a/corelib/src/test/bytes31_test.cairo +++ /dev/null @@ -1,192 +0,0 @@ -use core::bytes_31::{split_bytes31, bytes31_const}; - -const POW_2_248: felt252 = 0x100000000000000000000000000000000000000000000000000000000000000; - -#[test] -fn test_at() { - let b1 = bytes31_const::<0x01>(); - assert_eq!(b1.at(0), 0x01); - - let b17 = bytes31_const::<0x0102030405060708090a0b0c0d0e0f1011>(); - assert_eq!(b17.at(0), 0x11); - assert_eq!(b17.at(1), 0x10); - assert_eq!(b17.at(2), 0x0f); - assert_eq!(b17.at(14), 0x03); - assert_eq!(b17.at(15), 0x02); - assert_eq!(b17.at(16), 0x01); - - let b31 = bytes31_const::<0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f>(); - assert_eq!(b31.at(0), 0x1f); - assert_eq!(b31.at(1), 0x1e); - assert_eq!(b31.at(2), 0x1d); - assert_eq!(b31.at(14), 0x11); - assert_eq!(b31.at(15), 0x10); - assert_eq!(b31.at(16), 0x0f); - assert_eq!(b31.at(17), 0x0e); - assert_eq!(b31.at(29), 0x02); - assert_eq!(b31.at(30), 0x01); -} - -// Same as the previous test, but with [] instead of .at() -#[test] -fn test_index_view() { - let b1 = bytes31_const::<0x01>(); - assert_eq!(b1[0], 0x01); - - let b17 = bytes31_const::<0x0102030405060708090a0b0c0d0e0f1011>(); - assert_eq!(b17[0], 0x11); - assert_eq!(b17[1], 0x10); - assert_eq!(b17[2], 0x0f); - assert_eq!(b17[14], 0x03); - assert_eq!(b17[15], 0x02); - assert_eq!(b17[16], 0x01); - - let b31 = bytes31_const::<0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f>(); - assert_eq!(b31[0], 0x1f); - assert_eq!(b31[1], 0x1e); - assert_eq!(b31[2], 0x1d); - assert_eq!(b31[14], 0x11); - assert_eq!(b31[15], 0x10); - assert(b31[16] == 0x0f, 'wrong byte at index 16'); - assert(b31[17] == 0x0e, 'wrong byte at index 17'); - assert(b31[29] == 0x02, 'wrong byte at index 29'); - assert(b31[30] == 0x01, 'wrong byte at index 30'); -} - - -#[test] -fn test_bytes31_to_from_felt252() { - let zero_as_bytes31: Option = 0.try_into(); - assert(zero_as_bytes31.is_some(), '0 is not a bytes31'); - let zero_as_felt252 = zero_as_bytes31.unwrap().into(); - assert(zero_as_felt252 == 0_felt252, 'bad cast: 0'); - - let one_as_bytes31: Option = 1.try_into(); - assert(one_as_bytes31.is_some(), '1 is not a bytes31'); - let one_as_felt252 = one_as_bytes31.unwrap().into(); - assert(one_as_felt252 == 1_felt252, 'bad cast: 1'); - - let max_as_bytes31: Option = (POW_2_248 - 1).try_into(); - assert(max_as_bytes31.is_some(), '2^248 - 1 is not a bytes31'); - let max_as_felt252 = max_as_bytes31.unwrap().into(); - assert(max_as_felt252 == POW_2_248 - 1, 'bad cast: 2^248 - 1'); - - let out_of_range: Option = POW_2_248.try_into(); - assert(out_of_range.is_none(), '2^248 is a bytes31'); - - let out_of_range: Option = (-1).try_into(); - assert(out_of_range.is_none(), '-1 is a bytes31'); -} - -#[test] -fn test_u8_into_bytes31() { - let one_u8 = 1_u8; - let one_as_bytes31: bytes31 = one_u8.into(); - assert(one_as_bytes31.into() == 1_felt252, 'bad cast: 1'); - - let max_u8 = 0xff_u8; - let max_as_bytes31: bytes31 = max_u8.into(); - assert(max_as_bytes31.into() == 0xff_felt252, 'bad cast: 2^8 - 1'); -} - -#[test] -fn test_u16_into_bytes31() { - let one_u16 = 1_u16; - let one_as_bytes31: bytes31 = one_u16.into(); - assert(one_as_bytes31.into() == 1_felt252, 'bad cast: 1'); - - let max_u16 = 0xffff_u16; - let max_as_bytes31: bytes31 = max_u16.into(); - assert(max_as_bytes31.into() == 0xffff_felt252, 'bad cast: 2^16 - 1'); -} - -#[test] -fn test_u32_into_bytes31() { - let one_u32 = 1_u32; - let one_as_bytes31: bytes31 = one_u32.into(); - assert(one_as_bytes31.into() == 1_felt252, 'bad cast: 1'); - - let max_u32 = 0xffffffff_u32; - let max_as_bytes31: bytes31 = max_u32.into(); - assert(max_as_bytes31.into() == 0xffffffff_felt252, 'bad cast: 2^32 - 1'); -} - -#[test] -fn test_u64_into_bytes31() { - let one_u64 = 1_u64; - let one_as_bytes31: bytes31 = one_u64.into(); - assert(one_as_bytes31.into() == 1_felt252, 'bad cast: 1'); - - let max_u64 = 0xffffffffffffffff_u64; - let max_as_bytes31: bytes31 = max_u64.into(); - assert(max_as_bytes31.into() == 0xffffffffffffffff_felt252, 'bad cast: 2^64 - 1'); -} - -#[test] -fn test_u128_into_bytes31() { - let one_u128 = 1_u128; - let one_as_bytes31: bytes31 = one_u128.into(); - assert(one_as_bytes31.into() == 1_felt252, 'bad cast: 1'); - - let max_u128 = 0xffffffffffffffffffffffffffffffff_u128; - let max_as_bytes31: bytes31 = max_u128.into(); - assert( - max_as_bytes31.into() == 0xffffffffffffffffffffffffffffffff_felt252, 'bad cast: 2^128 - 1' - ); -} - -#[test] -fn test_split_bytes31() { - let (left, right) = split_bytes31(0x1122, 2, 1); - assert(left == 0x22, 'bad split (2, 1) left'); - assert(right == 0x11, 'bad split (2, 1) right'); - - let x = 0x112233445566778899aabbccddeeff00112233; - let (left, right) = split_bytes31(x, 19, 0); - assert(left == 0, 'bad split (19, 0) left'); - assert(right == 0x112233445566778899aabbccddeeff00112233, 'bad split (19, 0) right'); - - let (left, right) = split_bytes31(x, 19, 1); - assert(left == 0x33, 'bad split (19, 1) left'); - assert(right == 0x112233445566778899aabbccddeeff001122, 'bad split (19, 1) right'); - - let (left, right) = split_bytes31(x, 19, 15); - assert(left == 0x5566778899aabbccddeeff00112233, 'bad split (19, 15) left'); - assert(right == 0x11223344, 'bad split (19, 15) right'); - - let (left, right) = split_bytes31(x, 19, 16); - assert(left == 0x445566778899aabbccddeeff00112233, 'bad split (19, 16) left'); - assert(right == 0x112233, 'bad split (19, 16) right'); - - let (left, right) = split_bytes31(x, 19, 18); - assert(left == 0x2233445566778899aabbccddeeff00112233, 'bad split (19, 18) left'); - assert(right == 0x11, 'bad split (19, 18) right'); - - let (left, right) = split_bytes31(x, 19, 19); - assert(left == 0x112233445566778899aabbccddeeff00112233, 'bad split (19, 19) left'); - assert(right == 0, 'bad split (19, 19) right'); -} - -#[test] -fn test_equality() { - let b1 = bytes31_const::<0x01>(); - let b2 = bytes31_const::<0x0102>(); - let b3 = bytes31_const::<0x0201>(); - assert(b1 == b1, 'b1 != b1'); - assert(b2 == b2, 'b2 != b2'); - assert(b3 == b3, 'b3 != b3'); - assert(b1 != b2, 'b1 == b2'); - assert(b1 != b3, 'b1 == b3'); - assert(b2 != b3, 'b2 == b3'); - - let b4 = bytes31_const::<0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f>(); - let b5 = bytes31_const::<0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1e>(); - let b6 = bytes31_const::<0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e>(); - - assert(b4 == b4, 'b4 != b4'); - assert(b5 == b5, 'b5 != b5'); - assert(b6 == b6, 'b6 != b6'); - assert(b4 != b5, 'b4 == b5'); - assert(b4 != b6, 'b4 == b6'); - assert(b5 != b6, 'b5 == b6'); -} diff --git a/corelib/src/test/cmp_test.cairo b/corelib/src/test/cmp_test.cairo deleted file mode 100644 index f2890c590..000000000 --- a/corelib/src/test/cmp_test.cairo +++ /dev/null @@ -1,299 +0,0 @@ -use core::cmp::{max, min, minmax}; -use core::test::test_utils::{assert_eq, assert_ne}; - -// Integer tests - -#[test] -fn test_min_u8() { - assert_eq(@min(0_u8, 1_u8), @0_u8, '0 < 1'); - assert_eq(@min(0_u8, 1_u8), @0_u8, '0 < 1'); - assert_eq(@min(5_u8, 7_u8), @5_u8, '5 < 7'); - assert_eq(@min(255_u8, 128_u8), @128_u8, '128 < 255'); - assert_eq(@min(10_u8, 10_u8), @10_u8, '10 == 10'); - assert_eq(@min(0_u8, 0_u8), @0_u8, '0 == 0'); - assert_eq(@min(255_u8, 255_u8), @255_u8, '255 == 255'); - assert_eq(@min(3_u8, 4_u8), @3_u8, '3 < 4'); - assert_eq(@min(255_u8, 200_u8), @200_u8, '200 < 255'); - assert_eq(@min(250_u8, 253_u8), @250_u8, '250 < 253'); -} - -#[test] -fn test_max_u8() { - assert_eq(@max(0_u8, 1_u8), @1_u8, '1 > 0'); - assert_eq(@max(5_u8, 7_u8), @7_u8, '7 > 5'); - assert_eq(@max(255_u8, 128_u8), @255_u8, '255 > 128'); - assert_eq(@max(10_u8, 10_u8), @10_u8, '10 == 10'); - assert_eq(@max(0_u8, 0_u8), @0_u8, '0 == 0'); - assert_eq(@max(255_u8, 255_u8), @255_u8, '255 == 255'); - assert_eq(@max(100_u8, 200_u8), @200_u8, '200 > 100'); - assert_eq(@max(1_u8, 2_u8), @2_u8, '2 > 1'); - assert_eq(@max(120_u8, 130_u8), @130_u8, '130 > 120'); - assert_eq(@max(200_u8, 150_u8), @200_u8, '200 > 150'); -} - -#[test] -fn test_minmax_u8() { - assert!(minmax(0_u8, 1_u8) == (0_u8, 1_u8), "1 > 0"); - assert!(minmax(5_u8, 7_u8) == (5_u8, 7_u8), "7 > 5"); - assert!(minmax(255_u8, 128_u8) == (128_u8, 255_u8), "255 > 128"); - assert!(minmax(10_u8, 10_u8) == (10_u8, 10_u8), "10 == 10"); - assert!(minmax(0_u8, 0_u8) == (0_u8, 0_u8), "0 == 0"); - assert!(minmax(255_u8, 255_u8) == (255_u8, 255_u8), "255 == 255"); - assert!(minmax(100_u8, 200_u8) == (100_u8, 200_u8), "200 > 100"); - assert!(minmax(1_u8, 2_u8) == (1_u8, 2_u8), "2 > 1"); - assert!(minmax(120_u8, 130_u8) == (120_u8, 130_u8), "130 > 120"); - assert!(minmax(200_u8, 150_u8) == (150_u8, 200_u8), "200 > 150"); -} - -#[test] -fn test_min_u16() { - assert_eq(@min(0_u16, 1_u16), @0_u16, '0 < 1'); - assert_eq(@min(5_u16, 7_u16), @5_u16, '5 < 7'); - assert_eq(@min(65535_u16, 32768_u16), @32768_u16, '32768 < 65535'); - assert_eq(@min(10_u16, 10_u16), @10_u16, '10 == 10'); - assert_eq(@min(0_u16, 0_u16), @0_u16, '0 == 0'); - assert_eq(@min(65535_u16, 65535_u16), @65535_u16, '65535 == 65535'); - assert_eq(@min(100_u16, 200_u16), @100_u16, '100 < 200'); - assert_eq(@min(1_u16, 2_u16), @1_u16, '1 < 2'); - assert_eq(@min(32767_u16, 32766_u16), @32766_u16, '32766 < 32767'); - assert_eq(@min(400_u16, 300_u16), @300_u16, '300 < 400'); -} - -#[test] -fn test_max_u16() { - assert_eq(@max(0_u16, 1_u16), @1_u16, '1 > 0'); - assert_eq(@max(5_u16, 7_u16), @7_u16, '7 > 5'); - assert_eq(@max(65535_u16, 32768_u16), @65535_u16, '65535 > 32768'); - assert_eq(@max(10_u16, 10_u16), @10_u16, '10 == 10'); - assert_eq(@max(0_u16, 0_u16), @0_u16, '0 == 0'); - assert_eq(@max(65535_u16, 65535_u16), @65535_u16, '65535 == 65535'); - assert_eq(@max(100_u16, 200_u16), @200_u16, '200 > 100'); - assert_eq(@max(1_u16, 2_u16), @2_u16, '2 > 1'); - assert_eq(@max(32767_u16, 32766_u16), @32767_u16, '32767 > 32766'); - assert_eq(@max(400_u16, 300_u16), @400_u16, '400 > 300'); -} - -#[test] -fn test_min_u32() { - assert_eq(@min(0_u32, 1_u32), @0_u32, '0 < 1'); - assert_eq(@min(5_u32, 7_u32), @5_u32, '5 < 7'); - assert_eq(@min(4294967295_u32, 2147483648_u32), @2147483648_u32, '2147483648 < 4294967295'); - assert_eq(@min(10_u32, 10_u32), @10_u32, '10 == 10'); - assert_eq(@min(0_u32, 0_u32), @0_u32, '0 == 0'); - assert_eq(@min(4294967295_u32, 4294967295_u32), @4294967295_u32, '4294967295 == 4294967295'); - assert_eq(@min(100_u32, 200_u32), @100_u32, '100 < 200'); - assert_eq(@min(1_u32, 2_u32), @1_u32, '1 < 2'); - assert_eq(@min(2147483647_u32, 2147483646_u32), @2147483646_u32, '2147483646 < 2147483647'); - assert_eq(@min(400_u32, 300_u32), @300_u32, '300 < 400'); -} - -#[test] -fn test_max_u32() { - assert_eq(@max(0_u32, 1_u32), @1_u32, '1 > 0'); - assert_eq(@max(5_u32, 7_u32), @7_u32, '7 > 5'); - assert_eq(@max(4294967295_u32, 2147483648_u32), @4294967295_u32, '4294967295 > 2147483648'); - assert_eq(@max(10_u32, 10_u32), @10_u32, '10 == 10'); - assert_eq(@max(0_u32, 0_u32), @0_u32, '0 == 0'); - assert_eq(@max(4294967295_u32, 4294967295_u32), @4294967295_u32, '4294967295 == 4294967295'); - assert_eq(@max(100_u32, 200_u32), @200_u32, '200 > 100'); - assert_eq(@max(1_u32, 2_u32), @2_u32, '2 > 1'); - assert_eq(@max(2147483647_u32, 2147483646_u32), @2147483647_u32, '2147483647 > 2147483646'); - assert_eq(@max(400_u32, 300_u32), @400_u32, '400 > 300'); -} - -#[test] -fn test_min_u64() { - assert_eq(@min(0_u64, 1_u64), @0_u64, '0 < 1'); - assert_eq(@min(5_u64, 7_u64), @5_u64, '5 < 7'); - assert_eq( - @min(18446744073709551615_u64, 9223372036854775808_u64), - @9223372036854775808_u64, - '92233... < 18446...' - ); - assert_eq(@min(10_u64, 10_u64), @10_u64, '10 == 10'); - assert_eq(@min(0_u64, 0_u64), @0_u64, '0 == 0'); - assert_eq( - @min(18446744073709551615_u64, 18446744073709551615_u64), - @18446744073709551615_u64, - '18446... == 18446...' - ); - assert_eq(@min(100_u64, 200_u64), @100_u64, '100 < 200'); - assert_eq(@min(1_u64, 2_u64), @1_u64, '1 < 2'); - assert_eq( - @min(9223372036854775807_u64, 9223372036854775806_u64), - @9223372036854775806_u64, - '92233... < 92233...' - ); - assert_eq(@min(400_u64, 300_u64), @300_u64, '300 < 400'); -} - -#[test] -fn test_max_u64() { - assert_eq(@max(0_u64, 1_u64), @1_u64, '1 > 0'); - assert_eq(@max(5_u64, 7_u64), @7_u64, '7 > 5'); - assert_eq( - @max(18446744073709551615_u64, 9223372036854775808_u64), - @18446744073709551615_u64, - '18446... > 92233...' - ); - assert_eq(@max(10_u64, 10_u64), @10_u64, '10 == 10'); - assert_eq(@max(0_u64, 0_u64), @0_u64, '0 == 0'); - assert_eq( - @max(18446744073709551615_u64, 18446744073709551615_u64), - @18446744073709551615_u64, - '18446... == 18446...' - ); - assert_eq(@max(100_u64, 200_u64), @200_u64, '200 > 100'); - assert_eq(@max(1_u64, 2_u64), @2_u64, '2 > 1'); - assert_eq( - @max(9223372036854775807_u64, 9223372036854775806_u64), - @9223372036854775807_u64, - '92233... > 92233...' - ); - assert_eq(@max(400_u64, 300_u64), @400_u64, '400 > 300'); -} - -#[test] -fn test_min_u128() { - assert_eq(@min(0_u128, 1_u128), @0_u128, '0 < 1'); - assert_eq(@min(5_u128, 7_u128), @5_u128, '5 < 7'); - assert_eq( - @min( - 340282366920938463463374607431768211455_u128, - 170141183460469231731687303715884105728_u128 - ), - @170141183460469231731687303715884105728_u128, - '170141... < 340282...' - ); - assert_eq(@min(10_u128, 10_u128), @10_u128, '10 == 10'); - assert_eq(@min(0_u128, 0_u128), @0_u128, '0 == 0'); - assert_eq( - @min( - 340282366920938463463374607431768211455_u128, - 340282366920938463463374607431768211455_u128 - ), - @340282366920938463463374607431768211455_u128, - '340282366... == 340282366...' - ); - assert_eq(@min(100_u128, 200_u128), @100_u128, '100 < 200'); - assert_eq(@min(1_u128, 2_u128), @1_u128, '1 < 2'); - assert_eq( - @min( - 170141183460469231731687303715884105727_u128, - 170141183460469231731687303715884105726_u128 - ), - @170141183460469231731687303715884105726_u128, - '17014118... < 1701411834...' - ); - assert_eq(@min(400_u128, 300_u128), @300_u128, '300 < 400'); -} - -#[test] -fn test_max_u128() { - assert_eq(@max(0_u128, 1_u128), @1_u128, '1 > 0'); - assert_eq(@max(5_u128, 7_u128), @7_u128, '7 > 5'); - assert_eq( - @max(18446744073709551615_u128, 9223372036854775808_u128), - @18446744073709551615_u128, - '18446744... > 922337...' - ); - assert_eq(@max(10_u128, 10_u128), @10_u128, '10 == 10'); - assert_eq(@max(0_u128, 0_u128), @0_u128, '0 == 0'); - assert_eq( - @max(18446744073709551615_u128, 18446744073709551615_u128), - @18446744073709551615_u128, - '184467...== 184467' - ); - assert_eq(@max(100_u128, 200_u128), @200_u128, '200 > 100'); - assert_eq(@max(1_u128, 2_u128), @2_u128, '2 > 1'); - assert_eq( - @max(9223372036854775807_u128, 9223372036854775806_u128), - @9223372036854775807_u128, - '922337203... > 922337...' - ); - assert_eq(@max(400_u128, 300_u128), @400_u128, '400 > 300'); -} - -#[test] -fn test_min_u256() { - let a = u256 { low: 0, high: 0 }; - let b = u256 { low: 1, high: 0 }; - let c = u256 { low: 5, high: 0 }; - let d = u256 { low: 7, high: 0 }; - let e = u256 { low: 0, high: 1 }; - let f = u256 { low: 0, high: 2 }; - - assert_eq(@min(a, b), @a, 'a < b'); - assert_eq(@min(c, d), @c, 'c < d'); - assert_eq(@min(e, f), @e, 'e < f'); - assert_eq(@min(a, a), @a, 'a == a'); - assert_eq(@min(b, b), @b, 'b == b'); - assert_eq(@min(f, f), @f, 'f == f'); -} - -#[test] -fn test_max_u256() { - let a = u256 { low: 0, high: 0 }; - let b = u256 { low: 1, high: 0 }; - let c = u256 { low: 5, high: 0 }; - let d = u256 { low: 7, high: 0 }; - let e = u256 { low: 0, high: 1 }; - let f = u256 { low: 0, high: 2 }; - - assert_eq(@max(a, b), @b, 'b > a'); - assert_eq(@max(c, d), @d, 'd > c'); - assert_eq(@max(e, f), @f, 'f > e'); - assert_eq(@max(a, a), @a, 'a == a'); - assert_eq(@max(b, b), @b, 'b == b'); - assert_eq(@max(f, f), @f, 'f == f'); -} - -// User-defined types -#[derive(Drop, Copy)] -struct Foo { - val: u128 -} - -impl FooPartialOrd of PartialOrd { - fn le(lhs: Foo, rhs: Foo) -> bool { - lhs.val <= rhs.val - } - - fn ge(lhs: Foo, rhs: Foo) -> bool { - lhs.val >= rhs.val - } - - fn lt(lhs: Foo, rhs: Foo) -> bool { - lhs.val < rhs.val - } - - fn gt(lhs: Foo, rhs: Foo) -> bool { - lhs.val > rhs.val - } -} - -#[test] -fn test_min_foo() { - let a = Foo { val: 0 }; - let b = Foo { val: 1 }; - let c = Foo { val: 5 }; - let d = Foo { val: 7 }; - - assert_eq(@min(a, b).val, @a.val, 'a < b'); - assert_eq(@min(c, d).val, @c.val, 'c < d'); - assert_eq(@min(a, a).val, @a.val, 'a == a'); - assert_eq(@min(b, b).val, @b.val, 'b == b'); -} - -#[test] -fn test_max_foo() { - let a = Foo { val: 0 }; - let b = Foo { val: 1 }; - let c = Foo { val: 5 }; - let d = Foo { val: 7 }; - - assert_eq(@max(a, b).val, @b.val, 'b > a'); - assert_eq(@max(c, d).val, @d.val, 'd > c'); - assert_eq(@max(a, a).val, @a.val, 'a == a'); - assert_eq(@max(b, b).val, @b.val, 'b == b'); -} diff --git a/corelib/src/test/const_test.cairo b/corelib/src/test/const_test.cairo deleted file mode 100644 index f03654113..000000000 --- a/corelib/src/test/const_test.cairo +++ /dev/null @@ -1,134 +0,0 @@ -use core::box::BoxTrait; - -mod enum_value { - pub extern type Const; -} -mod value { - pub extern type Const; -} -mod struct0 { - pub extern type Const; -} -mod struct2 { - pub extern type Const; -} - -mod const_bool { - pub extern fn const_as_box() -> Box nopanic; -} - -#[test] -fn test_const_bool() { - assert!( - !const_bool::const_as_box::>, 0>().unbox() - ); - assert!( - const_bool::const_as_box::>, 0>().unbox() - ); -} - -mod const_felt252 { - pub extern fn const_as_box() -> Box nopanic; -} - -#[test] -fn test_const_felt252() { - assert!(const_felt252::const_as_box::, 1>().unbox() == 0); - assert!(const_felt252::const_as_box::, 2>().unbox() == -1); -} - -mod const_u8 { - pub extern fn const_as_box() -> Box nopanic; -} - -#[test] -fn test_const_u8() { - assert!(const_u8::const_as_box::, 0>().unbox() == 0); - assert!(const_u8::const_as_box::, 1>().unbox() == 255); -} - -mod const_u256 { - pub extern fn const_as_box() -> Box nopanic; -} - -#[test] -fn test_const_u256() { - assert!( - const_u256::const_as_box::< - struct2::Const, value::Const>, 0 - >() - .unbox() == 0x10 - ); - assert!( - const_u256::const_as_box::< - struct2::Const, value::Const>, 0 - >() - .unbox() == 0x1000000000000000000000000000000000 - ); -} - -#[derive(Copy, Drop, PartialEq, Debug)] -enum ThreeOptions { - A: felt252, - B: u256, - C, -} - -mod const_three_options { - pub extern fn const_as_box() -> Box nopanic; -} - -#[test] -fn test_complex_enum() { - assert!( - const_three_options::const_as_box::< - enum_value::Const>, 0 - >() - .unbox() == ThreeOptions::A(-1), - ); - assert!( - const_three_options::const_as_box::< - enum_value::Const< - ThreeOptions, - 1, - struct2::Const, value::Const,>, - >, - 1 - >() - .unbox() == ThreeOptions::B(0x2000000000000000000000000000000010) - ); - assert!( - const_three_options::const_as_box::< - enum_value::Const>, 1 - >() - .unbox() == ThreeOptions::C - ); -} - -#[derive(Copy, Drop, PartialEq, Debug)] -enum ThreeOptions2 { - A: felt252, - B: (u256, u256), - C, -} - -mod const_tuple_three_options { - pub extern fn const_as_box() -> Box< - (super::ThreeOptions2, super::ThreeOptions2) - > nopanic; -} - -#[test] -fn test_two_complex_enums() { - assert!( - const_tuple_three_options::const_as_box::< - struct2::Const< - (ThreeOptions2, ThreeOptions2), - enum_value::Const>, - enum_value::Const>, - >, - 0 - >() - .unbox() == (ThreeOptions2::A(1337), ThreeOptions2::C), - ); -} diff --git a/corelib/src/test/coupon_test.cairo b/corelib/src/test/coupon_test.cairo deleted file mode 100644 index 9311986ae..000000000 --- a/corelib/src/test/coupon_test.cairo +++ /dev/null @@ -1,26 +0,0 @@ -use core::test::test_utils::assert_eq; - -extern fn coupon_buy() -> T nopanic; - -fn arr_sum(arr: Array<(u128, arr_sum::Coupon)>) -> u128 nopanic { - match arr.pop_front_consume() { - Option::Some(( - rem, (elm, coupon) - )) => core::integer::u128_wrapping_add(elm, arr_sum(rem, __coupon__: coupon)), - Option::None => 0, - } -} - -#[test] -fn test_arr_sum() { - let mut arr: Array::<(u128, arr_sum::Coupon)> = array![]; - arr.append((3, coupon_buy())); - arr.append((4, coupon_buy())); - arr.append((5, coupon_buy())); - - let available_gas = core::testing::get_available_gas(); - let res = arr_sum(arr); - // Check that arr_sum did not consume any gas. - assert_eq(@core::testing::get_available_gas(), @available_gas, 'Gas was consumed by arr_sum'); - assert_eq(@res, @12, 'Wrong array sum.'); -} diff --git a/corelib/src/test/dict_test.cairo b/corelib/src/test/dict_test.cairo deleted file mode 100644 index bee920c52..000000000 --- a/corelib/src/test/dict_test.cairo +++ /dev/null @@ -1,150 +0,0 @@ -use core::dict::Felt252DictEntryTrait; -use core::test::test_utils::{assert_eq, assert_ne}; -use core::nullable; - -#[test] -fn test_dict_new() -> Felt252Dict { - Default::default() -} - -#[test] -fn test_dict_squash_empty() { - let mut dict: Felt252Dict = Default::default(); - let _squashed_dict = dict.squash(); -} - -#[test] -fn test_dict_default_val() { - let mut dict: Felt252Dict = Default::default(); - let default_val = dict.get(0); - assert_eq!(default_val, 0); -} - -#[test] -fn test_dict_write_read() { - let mut dict = Default::default(); - dict.insert(10, 110); - dict.insert(11, 111); - let val10 = dict[10]; - let val11 = dict[11]; - let val12 = dict[12]; - assert_eq!(val10, 110); - assert_eq!(val11, 111); - assert_eq!(val12, 0); -} - -#[test] -fn test_dict_entry() { - let mut dict = Default::default(); - dict.insert(10, 110); - let (entry, value) = dict.entry(10); - assert_eq!(value, 110); - let mut dict = entry.finalize(11); - assert_eq!(dict[10], 11); -} - -#[test] -fn test_dict_entry_uninitialized() { - let mut dict = Default::default(); - let (entry, value) = dict.entry(10); - assert_eq!(value, 0_felt252); - let mut dict = entry.finalize(110); - assert_eq!(dict[10], 110); -} - -#[test] -fn test_dict_update_twice() { - let mut dict = Default::default(); - dict.insert(10, 110); - let (entry, value) = dict.entry(10); - assert_eq!(value, 110); - dict = entry.finalize(11); - assert_eq!(dict[10], 11); - let (entry, value) = dict.entry(10); - assert_eq!(value, 11); - dict = entry.finalize(12); - assert_eq(@dict[10], @12, 'dict[10] == 12'); -} - - -/// Tests the destruction of a non-finalized `Felt252DictEntry`. -/// -/// Calls the destructor of the entry, which in turn calls the destructor of the `Felt252Dict`. -#[test] -fn test_dict_entry_destruct() { - let mut dict = Default::default(); - dict.insert(10, 110); - let (_entry, _value) = dict.entry(10); -} - -const KEY1: felt252 = 10; -const KEY2: felt252 = 21; -// KEY3 is ~37% * PRIME. -const KEY3: felt252 = 1343531647004637707094910297222796970954128321746173119103571679493202324940; -// KEY4 and KEY5 are ~92% * PRIME. -const KEY4: felt252 = 3334603141101959564751596861783084684819726025596122159217101666076094555684; -const KEY5: felt252 = 3334603141101959564751596861783084684819726025596122159217101666076094555685; - -/// Tests the big-keys behavior of `felt252_dict_squash()`. -/// -/// Uses a few keys to simulate the 3 possible cases in `validate_felt252_le`. -#[test] -fn test_dict_big_keys() { - let mut dict = Default::default(); - - dict.insert(KEY1, 1); - dict.insert(KEY2, 2); - dict.insert(KEY3, 3); - dict.insert(KEY4, 4); - dict.insert(KEY5, 5); - - assert_eq(@dict[KEY1], @1, 'KEY1'); - assert_eq(@dict[KEY2], @2, 'KEY2'); - assert_eq(@dict[KEY3], @3, 'KEY3'); - assert_eq(@dict[KEY4], @4, 'KEY4'); - assert_eq(@dict[KEY5], @5, 'KEY5'); -} - -#[test] -fn test_dict_of_nullable() { - let mut dict = Default::default(); - dict.insert(10, nullable::nullable_from_box(BoxTrait::new(1))); - dict.insert(11, nullable::nullable_from_box(BoxTrait::new(2))); - let val10 = dict[10].deref(); - let val11 = dict[11].deref(); - let val12 = dict[12]; - assert_eq(@val10, @1, 'dict[10] == 1'); - assert_eq(@val11, @2, 'dict[11] == 2'); - assert( - match nullable::match_nullable(val12) { - nullable::FromNullableResult::Null => true, - nullable::FromNullableResult::NotNull(_) => false, - }, - 'default_val == null' - ); -} - -#[test] -fn test_bool_dict() { - let mut bool_dict: Felt252Dict = Default::default(); - let _squashed_dict = bool_dict.squash(); - let mut bool_dict: Felt252Dict = Default::default(); - assert(!bool_dict.get(0), 'default_val != false'); - bool_dict.insert(1, true); - assert(bool_dict.get(1), 'bool_dict[1] != true'); -} - -#[test] -fn test_array_dict() { - let mut dict = Default::default(); - dict.insert(10, NullableTrait::new(array![1, 2, 3])); - let (entry, value) = dict.entry(10); - assert_eq(@value.deref(), @array![1, 2, 3], 'dict[10] == [1, 2, 3]'); - dict = entry.finalize(NullableTrait::new(array![4, 5])); - let (entry, value) = dict.entry(10); - assert_eq(@value.deref(), @array![4, 5], 'dict[10] == [4, 5]'); - dict = entry.finalize(nullable::null()); - let (_entry, value) = dict.entry(10); - assert(value.is_null(), 'dict[10] == null'); -} - diff --git a/corelib/src/test/ec_test.cairo b/corelib/src/test/ec_test.cairo deleted file mode 100644 index 249522a93..000000000 --- a/corelib/src/test/ec_test.cairo +++ /dev/null @@ -1,159 +0,0 @@ -use core::ec::{EcPoint, EcPointTrait, EcStateTrait}; -use core::ecdsa; -use core::option::OptionTrait; -use core::test::test_utils::{assert_eq, assert_ne}; -use core::traits::{Into, TryInto}; - -#[test] -#[should_panic] -fn test_ec_from_zero() { - EcPointTrait::new_from_x(0).expect('Not on curve.'); -} - -#[test] -fn test_ec_operations() { - // Beta + 2 is a square, and for x = 1 and alpha = 1, x^3 + alpha * x + beta = beta + 2. - let beta_p2_root = 2487829544412206244690656897973144572467842667075005257202960243805141046681; - let p = EcPointTrait::new_from_x(1).unwrap(); - let p_nz = p.try_into().unwrap(); - let (x, y) = p_nz.coordinates(); - assert_eq(@x, @1, 'x != 1'); - assert(y == beta_p2_root || y == -beta_p2_root, 'y is wrong'); - - let mut state = EcStateTrait::init(); - state.add(p_nz); - let q = state.finalize_nz().expect('zero point'); - let (qx, qy) = q.coordinates(); - assert_eq(@qx, @x, 'bad finalize x'); - assert_eq(@qy, @y, 'bad finalize y'); - - // Try doing the same thing with the EC op builtin. - let mut state = EcStateTrait::init(); - state.add_mul(1, p_nz); - let q3 = state.finalize_nz().expect('zero point'); - let (qx, qy) = q3.coordinates(); - assert_eq(@qx, @x, 'bad EC op x'); - assert_eq(@qy, @y, 'bad EC op y'); - - // Try computing `p + p` using the ec_mul function. - let double_p = p.mul(2); - let (double_x, double_y) = double_p.try_into().unwrap().coordinates(); - let expected_double_y = - 3572434102142093425782752266058856056057826477682467661647843687948039943621; - assert_eq( - @double_x, - @75984168971785666410219869038140038216102669781812169677875295511117260233, - 'bad double x' - ); - assert(double_y == expected_double_y || double_y == -expected_double_y, 'bad double y'); - - // Compute `2p - p`. - let (sub_x, sub_y) = (double_p - p).try_into().unwrap().coordinates(); - assert_eq(@sub_x, @x, 'bad x for 2p - p'); - assert_eq(@sub_y, @y, 'bad y for 2p - p'); - - // Compute `p - p`. - let p_diff: Option> = (p - p).try_into(); - assert(p_diff.is_none(), 'p - p did not return 0.'); - - // Compute `(-p) - p`. - let (sub2_x, sub2_y) = (-p - p).try_into().unwrap().coordinates(); - assert_eq(@sub2_x, @double_x, 'bad x for (-p) - p'); - assert_eq(@sub2_y, @-double_y, 'bad y for (-p) - p'); -} - -#[test] -#[should_panic] -fn test_bad_ec_point_creation() { - EcPointTrait::new(0, 0).unwrap(); -} - -#[test] -fn test_ec_point_finalization_zero() { - let state = EcStateTrait::init(); - let point_at_infinity = state.finalize_nz(); - assert(point_at_infinity.is_none(), 'Wrong point'); -} - -#[test] -fn test_ecdsa() { - let message_hash = 0x503f4bea29baee10b22a7f10bdc82dda071c977c1f25b8f3973d34e6b03b2c; - let public_key = 0x7b7454acbe7845da996377f85eb0892044d75ae95d04d3325a391951f35d2ec; - let signature_r = 0xbe96d72eb4f94078192c2e84d5230cde2a70f4b45c8797e2c907acff5060bb; - let signature_s = 0x677ae6bba6daf00d2631fab14c8acf24be6579f9d9e98f67aa7f2770e57a1f5; - assert( - ecdsa::check_ecdsa_signature(:message_hash, :public_key, :signature_r, :signature_s), - 'ecdsa returned false' - ); - assert( - !ecdsa::check_ecdsa_signature( - message_hash: message_hash + 1, :public_key, :signature_r, :signature_s - ), - 'ecdsa - wrong message' - ); - assert( - !ecdsa::check_ecdsa_signature( - :message_hash, public_key: public_key + 1, :signature_r, :signature_s - ), - 'ecdsa - wrong public_key' - ); - assert( - !ecdsa::check_ecdsa_signature( - :message_hash, :public_key, signature_r: signature_r + 1, :signature_s - ), - 'ecdsa - wrong r' - ); - assert( - !ecdsa::check_ecdsa_signature( - :message_hash, :public_key, :signature_r, signature_s: signature_s + 1 - ), - 'ecdsa - wrong s' - ); -} - -#[test] -fn test_ecdsa_recover_public_key() { - let message_hash = 0x503f4bea29baee10b22a7f10bdc82dda071c977c1f25b8f3973d34e6b03b2c; - let signature_r = 0xbe96d72eb4f94078192c2e84d5230cde2a70f4b45c8797e2c907acff5060bb; - let signature_s = 0x677ae6bba6daf00d2631fab14c8acf24be6579f9d9e98f67aa7f2770e57a1f5; - assert_eq( - @ecdsa::recover_public_key(:message_hash, :signature_r, :signature_s, y_parity: false) - .unwrap(), - @0x7b7454acbe7845da996377f85eb0892044d75ae95d04d3325a391951f35d2ec, - 'recover_ecdsa_public_key failed' - ); - assert( - ecdsa::check_ecdsa_signature( - :message_hash, - public_key: ecdsa::recover_public_key( - :message_hash, :signature_r, :signature_s, y_parity: true - ) - .unwrap(), - :signature_r, - :signature_s - ), - 'ecdsa returned false' - ); -} - -#[test] -fn test_ec_mul() { - let p = EcPointTrait::new( - x: 336742005567258698661916498343089167447076063081786685068305785816009957563, - y: 1706004133033694959518200210163451614294041810778629639790706933324248611779, - ) - .unwrap(); - let m = 2713877091499598330239944961141122840311015265600950719674787125185463975936; - let (x, y) = p.mul(m).try_into().unwrap().coordinates(); - - assert_eq( - @x, - @2881632108168892236043523177391659237686965655035240771134509747985978822780, - 'ec_mul failed (x).' - ); - assert_eq( - @y, - @591135563672138037839394207500885413019058613584891498394077262936524140839, - 'ec_mul failed (y).' - ); -} diff --git a/corelib/src/test/felt_test.cairo b/corelib/src/test/felt_test.cairo deleted file mode 100644 index 1276e8c96..000000000 --- a/corelib/src/test/felt_test.cairo +++ /dev/null @@ -1,19 +0,0 @@ -use core::test::test_utils::{assert_eq, assert_ne}; - -#[test] -fn test_felt252_operators() { - assert_eq(@(1 + 3), @4, '1 + 3 == 4'); - assert_eq(@(3 + 6), @9, '3 + 6 == 9'); - assert_eq(@(3 - 1), @2, '3 - 1 == 2'); - assert_eq(@(1231 - 231), @1000, '1231-231=1000'); - assert_eq(@(1 * 3), @3, '1 * 3 == 3'); - assert_eq(@(3 * 6), @18, '3 * 6 == 18'); - assert_eq(@(-3), @(1 - 4), '-3 == 1 - 4'); -} - -#[test] -fn test_felt252_clone() { - let felt252_snap = @2; - let felt252_clone = felt252_snap.clone(); - assert_eq(@felt252_clone, @2, 'felt252_clone == 2'); -} diff --git a/corelib/src/test/fmt_test.cairo b/corelib/src/test/fmt_test.cairo deleted file mode 100644 index 57fabbf2d..000000000 --- a/corelib/src/test/fmt_test.cairo +++ /dev/null @@ -1,80 +0,0 @@ -#[test] -fn test_format() { - let ba: ByteArray = "hello"; - assert(format!("{}", ba) == ba, 'byte array bad formatting'); - assert(format!("{}", 97_felt252) == "97", 'felt252 bad formatting'); - assert(format!("{}", 97_usize) == "97", 'usize bad formatting'); - assert(format!("{}", 34 - 5) == "29", 'expression bad formatting'); - assert(format!("no_format") == "no_format", 'no args bad formatting'); - assert(format!("{}{}", 12_usize, 14_u32) == "1214", 'two args bad formatting'); - assert(format!("{0}{0}", 12_usize) == "1212", 'positional bad formatting'); - assert(format!("{}{1}", 12_usize, 14_u32) == "1214", 'positional mix bad formatting'); - assert(format!("{ba}_{}_{}_{1}", 12, 14_u32) == "hello_12_14_14", 'full mix bad formatting'); - assert(format!("{{{{}}}}") == "{{}}", 'special cases bad formatting'); - let nz_value: NonZero = 1.try_into().unwrap(); - assert(format!("{}", nz_value) == "1", 'non zero bad formatting'); -} - -#[derive(Debug, Drop)] -struct StructExample { - felt_value: felt252, - bool_value: bool, - byte_array_value: ByteArray, - enum_value: EnumExample, -} - -#[derive(Debug, Drop)] -enum EnumExample { - Empty, - FeltValue: felt252, - BoolValue: bool, -} - -#[test] -fn test_format_debug() { - let ba: ByteArray = "hello"; - assert(format!("{:?}", ba) == "\"hello\"", 'byte array bad formatting'); - assert(format!("{:?}", 97_felt252) == "97", 'felt252 bad formatting'); - assert(format!("{:?}", 97_usize) == "97", 'usize bad formatting'); - assert(format!("{:?}{:?}", 12_usize, 14_u32) == "1214", 'two args bad formatting'); - assert(format!("{0:?}{0:?}", 12_usize) == "1212", 'positional bad formatting'); - assert(format!("{:?}{1:?}", 12_usize, 14_u32) == "1214", 'positional mix bad formatting'); - assert( - format!("{ba:?}_{:?}_{:?}_{1:?}", 12, 14_u32) == "\"hello\"_12_14_14", - 'full mix bad formatting' - ); - assert( - format!("{:?}", EnumExample::Empty) == "EnumExample::Empty(())", 'bad enum empty derive fmt' - ); - assert( - format!("{:?}", EnumExample::FeltValue(4)) == "EnumExample::FeltValue(4)", - 'bad derive enum fmt' - ); - assert( - format!( - "{:?}", - StructExample { - felt_value: 6, - bool_value: false, - byte_array_value: "ByteArray", - enum_value: EnumExample::BoolValue(true) - } - ) == "StructExample { felt_value: 6, bool_value: false, byte_array_value: \"ByteArray\", enum_value: EnumExample::BoolValue(true) }", - 'bad derive struct formatting' - ); - assert( - format!("{:?}", ((), (1,), (2, 3), (4, 5, 6))) == "((), (1,), (2, 3), (4, 5, 6))", - 'bad tuple fmt' - ); - assert(format!("{:?}", core::box::BoxTrait::new(1)) == "&1", 'bad box fmt'); - assert( - format!("{:?}", core::nullable::NullableTrait::new(1)) == "&1", 'bad nullable value fmt' - ); - assert(format!("{:?}", core::nullable::null::()) == "null", 'bad null fmt'); -} - -#[test] -fn test_array_debug() { - let arr = array![1, 2, 3]; - assert(format!("{:?}", arr) == "[1, 2, 3]", 'bad array fmt'); -} diff --git a/corelib/src/test/hash_test.cairo b/corelib/src/test/hash_test.cairo deleted file mode 100644 index 93f9eb965..000000000 --- a/corelib/src/test/hash_test.cairo +++ /dev/null @@ -1,89 +0,0 @@ -use core::test::test_utils::{assert_eq, assert_ne}; -use core::hash::{HashStateTrait, HashStateExTrait}; -use core::poseidon::PoseidonTrait; - -#[test] -fn test_pedersen_hash() { - assert_eq( - @core::pedersen::pedersen(1, 2), - @2592987851775965742543459319508348457290966253241455514226127639100457844774, - 'Wrong hash value' - ); -} - -#[test] -fn test_poseidon_hades_permutation() { - let (s0, s1, s2) = core::poseidon::hades_permutation(1, 2, 3); - assert_eq( - @s0, - @442682200349489646213731521593476982257703159825582578145778919623645026501, - 'wrong s0' - ); - assert_eq( - @s1, - @2233832504250924383748553933071188903279928981104663696710686541536735838182, - 'wrong s1' - ); - assert_eq( - @s2, - @2512222140811166287287541003826449032093371832913959128171347018667852712082, - 'wrong s2' - ); -} - -#[test] -fn test_poseidon_hash_span() { - // Test odd number of inputs. - assert_eq( - @core::poseidon::poseidon_hash_span(array![1, 2, 3].span()), - @0x2f0d8840bcf3bc629598d8a6cc80cb7c0d9e52d93dab244bbf9cd0dca0ad082, - 'wrong result' - ); - - // Test even number of inputs. - assert_eq( - @core::poseidon::poseidon_hash_span(array![1, 2, 3, 4].span()), - @0x26e3ad8b876e02bc8a4fc43dad40a8f81a6384083cabffa190bcf40d512ae1d, - 'wrong result' - ); -} - -#[derive(Hash)] -enum EnumForHash { - First, - Second: felt252, - Third: (felt252, felt252), -} - -#[derive(Hash)] -struct StructForHash { - first: (), - second: felt252, - third: (felt252, felt252), -} - -#[test] -fn test_user_defined_hash() { - assert_eq( - @PoseidonTrait::new().update_with(EnumForHash::First).finalize(), - @PoseidonTrait::new().update(0).finalize(), - 'Bad hash of EnumForHash::First', - ); - assert_eq( - @PoseidonTrait::new().update_with(EnumForHash::Second(5)).finalize(), - @PoseidonTrait::new().update(1).update(5).finalize(), - 'Bad hash of EnumForHash::Second', - ); - assert_eq( - @PoseidonTrait::new().update_with(EnumForHash::Third((6, 8))).finalize(), - @PoseidonTrait::new().update(2).update(6).update(8).finalize(), - 'Bad hash of EnumForHash::Third', - ); - assert_eq( - @PoseidonTrait::new() - .update_with(StructForHash { first: (), second: 10, third: (6, 17) }) - .finalize(), - @PoseidonTrait::new().update(10).update(6).update(17).finalize(), - 'Bad hash of StructForHash', - ); -} diff --git a/corelib/src/test/integer_test.cairo b/corelib/src/test/integer_test.cairo deleted file mode 100644 index 1a7d4dc38..000000000 --- a/corelib/src/test/integer_test.cairo +++ /dev/null @@ -1,1950 +0,0 @@ -use core::{ - integer, - integer::{ - BoundedInt, u128_sqrt, u128_wrapping_sub, u16_sqrt, u256_sqrt, u256_wide_mul, u32_sqrt, - u512_safe_div_rem_by_u256, u512, u64_sqrt, u8_sqrt - } -}; -use core::test::test_utils::{assert_eq, assert_ne, assert_le, assert_lt, assert_gt, assert_ge}; - -#[test] -fn test_u8_operators() { - assert_eq(@1_u8, @1_u8, '1 == 1'); - assert_ne(@1_u8, @2_u8, '1 != 2'); - assert_eq(@(1_u8 + 3_u8), @4_u8, '1 + 3 == 4'); - assert_eq(@(3_u8 + 6_u8), @9_u8, '3 + 6 == 9'); - assert_eq(@(3_u8 - 1_u8), @2_u8, '3 - 1 == 2'); - assert_eq(@(1_u8 * 3_u8), @3_u8, '1 * 3 == 3'); - assert_eq(@(2_u8 * 4_u8), @8_u8, '2 * 4 == 8'); - assert_eq(@(19_u8 / 7_u8), @2_u8, '19 / 7 == 2'); - assert_eq(@(19_u8 % 7_u8), @5_u8, '19 % 7 == 5'); - assert_eq(@(231_u8 - 131_u8), @100_u8, '231-131=100'); - assert_eq(@((1_u8 | 2_u8)), @3_u8, '1 | 2 == 3'); - assert_eq(@((1_u8 & 2_u8)), @0_u8, '1 & 2 == 0'); - assert_eq(@((1_u8 ^ 2_u8)), @3_u8, '1 ^ 2 == 3'); - assert_eq(@((2_u8 | 2_u8)), @2_u8, '2 | 2 == 2'); - assert_eq(@((2_u8 & 2_u8)), @2_u8, '2 & 2 == 2'); - assert_eq(@((2_u8 & 3_u8)), @2_u8, '2 & 3 == 2'); - assert_eq(@((3_u8 ^ 6_u8)), @5_u8, '3 ^ 6 == 5'); - assert_lt(1_u8, 4_u8, '1 < 4'); - assert_le(1_u8, 4_u8, '1 <= 4'); - assert(!(4_u8 < 4_u8), '!(4 < 4)'); - assert_le(5_u8, 5_u8, '5 <= 5'); - assert(!(5_u8 <= 4_u8), '!(5 <= 8)'); - assert_gt(5_u8, 2_u8, '5 > 2'); - assert_ge(5_u8, 2_u8, '5 >= 2'); - assert(!(3_u8 > 3_u8), '!(3 > 3)'); - assert_ge(3_u8, 3_u8, '3 >= 3'); - assert_eq(@u8_sqrt(9), @3, 'u8_sqrt(9) == 3'); - assert_eq(@u8_sqrt(10), @3, 'u8_sqrt(10) == 3'); - assert_eq(@u8_sqrt(0x40), @0x8, 'u8_sqrt(2^6) == 2^3'); - assert_eq(@u8_sqrt(0xff), @0xf, 'Wrong square root result.'); - assert_eq(@u8_sqrt(1), @1, 'u8_sqrt(1) == 1'); - assert_eq(@u8_sqrt(0), @0, 'u8_sqrt(0) == 0'); - assert_eq(@~0x00_u8, @0xff, '~0x00 == 0xff'); - assert_eq(@~0x81_u8, @0x7e, '~0x81 == 0x7e'); -} - -#[test] -#[should_panic] -fn test_u8_sub_overflow_1() { - 0_u8 - 1_u8; -} - -#[test] -#[should_panic] -fn test_u8_sub_overflow_2() { - 0_u8 - 3_u8; -} - -#[test] -#[should_panic] -fn test_u8_sub_overflow_3() { - 1_u8 - 3_u8; -} - -#[test] -#[should_panic] -fn test_u8_sub_overflow_4() { - 100_u8 - 250_u8; -} - -#[test] -#[should_panic] -fn test_u8_add_overflow_1() { - 128_u8 + 128_u8; -} - -#[test] -#[should_panic] -fn test_u8_add_overflow_2() { - 200_u8 + 60_u8; -} - -#[test] -#[should_panic] -fn test_u8_mul_overflow_1() { - 0x10_u8 * 0x10_u8; -} - -#[test] -#[should_panic] -fn test_u8_mul_overflow_2() { - 0x11_u8 * 0x10_u8; -} - -#[test] -#[should_panic] -fn test_u8_mul_overflow_3() { - 2_u8 * 0x80_u8; -} - -#[test] -#[should_panic(expected: ('Division by 0',))] -fn test_u8_div_by_0() { - 2_u8 / 0_u8; -} - -#[test] -#[should_panic] -fn test_u8_mod_by_0() { - 2_u8 % 0_u8; -} - -#[test] -fn test_u16_operators() { - assert_eq(@1_u16, @1_u16, '1 == 1'); - assert_ne(@1_u16, @2_u16, '1 != 2'); - assert_eq(@(1_u16 + 3_u16), @4_u16, '1 + 3 == 4'); - assert_eq(@(3_u16 + 6_u16), @9_u16, '3 + 6 == 9'); - assert_eq(@(3_u16 - 1_u16), @2_u16, '3 - 1 == 2'); - assert_eq(@(231_u16 - 131_u16), @100_u16, '231-131=100'); - assert_eq(@(1_u16 * 3_u16), @3_u16, '1 * 3 == 3'); - assert_eq(@(2_u16 * 4_u16), @8_u16, '2 * 4 == 8'); - assert_eq(@(51725_u16 / 7_u16), @7389_u16, '51725 / 7 == 7389'); - assert_eq(@(51725_u16 % 7_u16), @2_u16, '51725 % 7 == 2'); - assert_eq(@((1_u16 | 2_u16)), @3_u16, '1 | 2 == 3'); - assert_eq(@((1_u16 & 2_u16)), @0_u16, '1 & 2 == 0'); - assert_eq(@((1_u16 ^ 2_u16)), @3_u16, '1 ^ 2 == 3'); - assert_eq(@((2_u16 | 2_u16)), @2_u16, '2 | 2 == 2'); - assert_eq(@((2_u16 & 2_u16)), @2_u16, '2 & 2 == 2'); - assert_eq(@((2_u16 & 3_u16)), @2_u16, '2 & 3 == 2'); - assert_eq(@((3_u16 ^ 6_u16)), @5_u16, '3 ^ 6 == 5'); - assert_lt(1_u16, 4_u16, '1 < 4'); - assert_le(1_u16, 4_u16, '1 <= 4'); - assert(!(4_u16 < 4_u16), '!(4 < 4)'); - assert_le(4_u16, 4_u16, '4 <= 4'); - assert_gt(5_u16, 2_u16, '5 > 2'); - assert_ge(5_u16, 2_u16, '5 >= 2'); - assert(!(3_u16 > 3_u16), '!(3 > 3)'); - assert_ge(3_u16, 3_u16, '3 >= 3'); - assert_eq(@u16_sqrt(9), @3, 'u16_sqrt(9) == 3'); - assert_eq(@u16_sqrt(10), @3, 'u16_sqrt(10) == 3'); - assert_eq(@u16_sqrt(0x400), @0x20, 'u16_sqrt(2^10) == 2^5'); - assert_eq(@u16_sqrt(0xffff), @0xff, 'Wrong square root result.'); - assert_eq(@u16_sqrt(1), @1, 'u64_sqrt(1) == 1'); - assert_eq(@u16_sqrt(0), @0, 'u64_sqrt(0) == 0'); - assert_eq(@~0x0000_u16, @0xffff, '~0x0000 == 0xffff'); - assert_eq(@~0x8421_u16, @0x7bde, '~0x8421 == 0x7bde'); -} - -#[test] -#[should_panic] -fn test_u16_sub_overflow_1() { - 0_u16 - 1_u16; -} - -#[test] -#[should_panic] -fn test_u16_sub_overflow_2() { - 0_u16 - 3_u16; -} - -#[test] -#[should_panic] -fn test_u16_sub_overflow_3() { - 1_u16 - 3_u16; -} - -#[test] -#[should_panic] -fn test_u16_sub_overflow_4() { - 100_u16 - 250_u16; -} - -#[test] -#[should_panic] -fn test_u16_add_overflow_1() { - 0x8000_u16 + 0x8000_u16; -} - -#[test] -#[should_panic] -fn test_u16_add_overflow_2() { - 0x9000_u16 + 0x8001_u16; -} - -#[test] -#[should_panic] -fn test_u16_mul_overflow_1() { - 0x100_u16 * 0x100_u16; -} - -#[test] -#[should_panic] -fn test_u16_mul_overflow_2() { - 0x101_u16 * 0x100_u16; -} - -#[test] -#[should_panic] -fn test_u16_mul_overflow_3() { - 2_u16 * 0x8000_u16; -} - -#[test] -#[should_panic(expected: ('Division by 0',))] -fn test_u16_div_by_0() { - 2_u16 / 0_u16; -} - -#[test] -#[should_panic] -fn test_u16_mod_by_0() { - 0_u16 % 0_u16; -} - -#[test] -fn test_u32_operators() { - assert_eq(@1_u32, @1_u32, '1 == 1'); - assert_ne(@1_u32, @2_u32, '1 != 2'); - assert_eq(@(1_u32 + 3_u32), @4_u32, '1 + 3 == 4'); - assert_eq(@(3_u32 + 6_u32), @9_u32, '3 + 6 == 9'); - assert_eq(@(3_u32 - 1_u32), @2_u32, '3 - 1 == 2'); - assert_eq(@(231_u32 - 131_u32), @100_u32, '231-131=100'); - assert_eq(@(1_u32 * 3_u32), @3_u32, '1 * 3 == 3'); - assert_eq(@(2_u32 * 4_u32), @8_u32, '2 * 4 == 8'); - assert_eq(@(510670725_u32 / 7_u32), @72952960_u32, '510670725 / 7 == 72952960'); - assert_eq(@(510670725_u32 % 7_u32), @5_u32, '510670725 % 7 == 5'); - assert_eq(@((1_u32 | 2_u32)), @3_u32, '1 | 2 == 3'); - assert_eq(@((1_u32 & 2_u32)), @0_u32, '1 & 2 == 0'); - assert_eq(@((1_u32 ^ 2_u32)), @3_u32, '1 ^ 2 == 3'); - assert_eq(@((2_u32 | 2_u32)), @2_u32, '2 | 2 == 2'); - assert_eq(@((2_u32 & 2_u32)), @2_u32, '2 & 2 == 2'); - assert_eq(@((2_u32 & 3_u32)), @2_u32, '2 & 3 == 2'); - assert_eq(@((3_u32 ^ 6_u32)), @5_u32, '3 ^ 6 == 5'); - assert_lt(1_u32, 4_u32, '1 < 4'); - assert_le(1_u32, 4_u32, '1 <= 4'); - assert(!(4_u32 < 4_u32), '!(4 < 4)'); - assert_le(4_u32, 4_u32, '4 <= 4'); - assert_gt(5_u32, 2_u32, '5 > 2'); - assert_ge(5_u32, 2_u32, '5 >= 2'); - assert(!(3_u32 > 3_u32), '!(3 > 3)'); - assert_ge(3_u32, 3_u32, '3 >= 3'); - assert_eq(@u32_sqrt(9), @3, 'u32_sqrt(9) == 3'); - assert_eq(@u32_sqrt(10), @3, 'u32_sqrt(10) == 3'); - assert_eq(@u32_sqrt(0x100000), @0x400, 'u32_sqrt(2^20) == 2^10'); - assert_eq(@u32_sqrt(0xffffffff), @0xffff, 'Wrong square root result.'); - assert_eq(@u32_sqrt(1), @1, 'u64_sqrt(1) == 1'); - assert_eq(@u32_sqrt(0), @0, 'u64_sqrt(0) == 0'); - assert_eq(@~0x00000000_u32, @0xffffffff, '~0x00000000 == 0xffffffff'); - assert_eq(@~0x12345678_u32, @0xedcba987, '~0x12345678 == 0xedcba987'); -} - -#[test] -#[should_panic] -fn test_u32_sub_overflow_1() { - 0_u32 - 1_u32; -} - -#[test] -#[should_panic] -fn test_u32_sub_overflow_2() { - 0_u32 - 3_u32; -} - -#[test] -#[should_panic] -fn test_u32_sub_overflow_3() { - 1_u32 - 3_u32; -} - -#[test] -#[should_panic] -fn test_u32_sub_overflow_4() { - 100_u32 - 250_u32; -} - -#[test] -#[should_panic] -fn test_u32_add_overflow_1() { - 0x80000000_u32 + 0x80000000_u32; -} - -#[test] -#[should_panic] -fn test_u32_add_overflow_2() { - 0x90000000_u32 + 0x80000001_u32; -} - -#[test] -#[should_panic] -fn test_u32_mul_overflow_1() { - 0x10000_u32 * 0x10000_u32; -} - -#[test] -#[should_panic] -fn test_u32_mul_overflow_2() { - 0x10001_u32 * 0x10000_u32; -} - -#[test] -#[should_panic] -fn test_u32_mul_overflow_3() { - 2_u32 * 0x80000000_u32; -} - -#[test] -#[should_panic(expected: ('Division by 0',))] -fn test_u32_div_by_0() { - 2_u32 / 0_u32; -} - -#[test] -#[should_panic] -fn test_u32_mod_by_0() { - 0_u32 % 0_u32; -} - -#[test] -fn test_u64_operators() { - assert_eq(@1_u64, @1_u64, '1 == 1'); - assert_ne(@1_u64, @2_u64, '1 != 2'); - assert_eq(@(1_u64 + 3_u64), @4_u64, '1 + 3 == 4'); - assert_eq(@(3_u64 + 6_u64), @9_u64, '3 + 6 == 9'); - assert_eq(@(3_u64 - 1_u64), @2_u64, '3 - 1 == 2'); - assert_eq(@(231_u64 - 131_u64), @100_u64, '231-131=100'); - assert_eq(@(1_u64 * 3_u64), @3_u64, '1 * 3 == 3'); - assert_eq(@(2_u64 * 4_u64), @8_u64, '2 * 4 == 8'); - assert_eq( - @(5010670477878974275_u64 / 7_u64), @715810068268424896_u64, 'Wrong division result.' - ); - assert_eq(@(5010670477878974275_u64 % 7_u64), @3_u64, '5010670477878974275 % 7 == 3'); - assert_eq(@((1_u64 | 2_u64)), @3_u64, '1 | 2 == 3'); - assert_eq(@((1_u64 & 2_u64)), @0_u64, '1 & 2 == 0'); - assert_eq(@((1_u64 ^ 2_u64)), @3_u64, '1 ^ 2 == 3'); - assert_eq(@((2_u64 | 2_u64)), @2_u64, '2 | 2 == 2'); - assert_eq(@((2_u64 & 2_u64)), @2_u64, '2 & 2 == 2'); - assert_eq(@((2_u64 & 3_u64)), @2_u64, '2 & 3 == 2'); - assert_eq(@((3_u64 ^ 6_u64)), @5_u64, '3 ^ 6 == 5'); - assert_lt(1_u64, 4_u64, '1 < 4'); - assert_le(1_u64, 4_u64, '1 <= 4'); - assert(!(4_u64 < 4_u64), '!(4 < 4)'); - assert_le(4_u64, 4_u64, '4 <= 4'); - assert_gt(5_u64, 2_u64, '5 > 2'); - assert_ge(5_u64, 2_u64, '5 >= 2'); - assert(!(3_u64 > 3_u64), '!(3 > 3)'); - assert_ge(3_u64, 3_u64, '3 >= 3'); - assert_eq(@u64_sqrt(9), @3, 'u64_sqrt(9) == 3'); - assert_eq(@u64_sqrt(10), @3, 'u64_sqrt(10) == 3'); - assert_eq(@u64_sqrt(0x10000000000), @0x100000, 'u64_sqrt(2^40) == 2^20'); - assert_eq(@u64_sqrt(0xffffffffffffffff), @0xffffffff, 'Wrong square root result.'); - assert_eq(@u64_sqrt(1), @1, 'u64_sqrt(1) == 1'); - assert_eq(@u64_sqrt(0), @0, 'u64_sqrt(0) == 0'); - assert_eq(@~0x0000000000000000_u64, @0xffffffffffffffff, '~0x0..0 == 0xf..f'); - assert_eq(@~0x123456789abcdef1_u64, @0xedcba9876543210e, '~0x12..ef1 == 0xed..10e'); -} - -#[test] -#[should_panic] -fn test_u64_sub_overflow_1() { - 0_u64 - 1_u64; -} - -#[test] -#[should_panic] -fn test_u64_sub_overflow_2() { - 0_u64 - 3_u64; -} - -#[test] -#[should_panic] -fn test_u64_sub_overflow_3() { - 1_u64 - 3_u64; -} - -#[test] -#[should_panic] -fn test_u64_sub_overflow_4() { - 100_u64 - 250_u64; -} - -#[test] -#[should_panic] -fn test_u64_add_overflow_1() { - 0x8000000000000000_u64 + 0x8000000000000000_u64; -} - -#[test] -#[should_panic] -fn test_u64_add_overflow_2() { - 0x9000000000000000_u64 + 0x8000000000000001_u64; -} - -#[test] -#[should_panic] -fn test_u64_mul_overflow_1() { - 0x100000000_u64 * 0x100000000_u64; -} - -#[test] -#[should_panic] -fn test_u64_mul_overflow_2() { - 0x100000001_u64 * 0x100000000_u64; -} - -#[test] -#[should_panic] -fn test_u64_mul_overflow_3() { - 2_u64 * 0x8000000000000000_u64; -} - -#[test] -#[should_panic(expected: ('Division by 0',))] -fn test_u64_div_by_0() { - 2_u64 / 0_u64; -} - -#[test] -#[should_panic] -fn test_u64_mod_by_0() { - 0_u64 % 0_u64; -} - -#[test] -fn test_u128_operators() { - assert_eq(@1_u128, @1_u128, '1 == 1'); - assert_ne(@1_u128, @2_u128, '1 != 2'); - assert_eq(@(1_u128 + 3_u128), @4_u128, '1 + 3 == 4'); - assert_eq(@(3_u128 + 6_u128), @9_u128, '3 + 6 == 9'); - assert_eq(@(3_u128 - 1_u128), @2_u128, '3 - 1 == 2'); - assert_eq(@(1231_u128 - 231_u128), @1000_u128, '1231-231=1000'); - assert_eq(@(1_u128 * 3_u128), @3_u128, '1 * 3 == 3'); - assert_eq(@(2_u128 * 4_u128), @8_u128, '2 * 4 == 8'); - assert_eq(@(8_u128 / 2_u128), @4_u128, '8 / 2 == 4'); - assert_eq(@(8_u128 % 2_u128), @0_u128, '8 % 2 == 0'); - assert_eq(@(7_u128 / 3_u128), @2_u128, '7 / 3 == 2'); - assert_eq(@(7_u128 % 3_u128), @1_u128, '7 % 3 == 1'); - assert_lt(1_u128, 4_u128, '1 < 4'); - assert_le(1_u128, 4_u128, '1 <= 4'); - assert(!(4_u128 < 4_u128), '!(4 < 4)'); - assert_le(4_u128, 4_u128, '4 <= 4'); - assert_gt(5_u128, 2_u128, '5 > 2'); - assert_ge(5_u128, 2_u128, '5 >= 2'); - assert(!(3_u128 > 3_u128), '!(3 > 3)'); - assert_ge(3_u128, 3_u128, '3 >= 3'); - assert_eq(@((1_u128 | 2_u128)), @3_u128, '1 | 2 == 3'); - assert_eq(@((1_u128 & 2_u128)), @0_u128, '1 & 2 == 0'); - assert_eq(@((1_u128 ^ 2_u128)), @3_u128, '1 ^ 2 == 3'); - assert_eq(@((2_u128 | 2_u128)), @2_u128, '2 | 2 == 2'); - assert_eq(@((2_u128 & 2_u128)), @2_u128, '2 & 2 == 2'); - assert_eq(@((2_u128 & 3_u128)), @2_u128, '2 & 3 == 2'); - assert_eq(@((3_u128 ^ 6_u128)), @5_u128, '3 ^ 6 == 5'); - assert_eq(@u128_sqrt(9), @3, 'u128_sqrt(9) == 3'); - assert_eq(@u128_sqrt(10), @3, 'u128_sqrt(10) == 3'); - assert_eq( - @u128_sqrt(0x10000000000000000000000000), @0x4000000000000, 'u128_sqrt(2^100) == 2^50' - ); - assert_eq( - @u128_sqrt(0xffffffffffffffffffffffffffffffff), - @0xffffffffffffffff, - 'Wrong square root result.' - ); - assert_eq(@u128_sqrt(1), @1, 'u128_sqrt(1) == 1'); - assert_eq(@u128_sqrt(0), @0, 'u128_sqrt(0) == 0'); - assert_eq( - @~0x00000000000000000000000000000000_u128, - @0xffffffffffffffffffffffffffffffff, - '~0x0..0 == 0xf..f' - ); - assert_eq( - @~0x123456789abcdef123456789abcdef12_u128, - @0xedcba9876543210edcba9876543210ed, - '~0x12..ef12 == 0xed..10ed' - ); -} - -fn pow_2_64() -> u128 { - 0x10000000000000000_u128 -} - -#[test] -#[should_panic] -fn test_u128_sub_overflow_1() { - 0_u128 - 1_u128; -} - -#[test] -#[should_panic] -fn test_u128_sub_overflow_2() { - 0_u128 - 3_u128; -} - -#[test] -#[should_panic] -fn test_u128_sub_overflow_3() { - 1_u128 - 3_u128; -} - -#[test] -#[should_panic] -fn test_u128_sub_overflow_4() { - 100_u128 - 1000_u128; -} - -#[test] -fn test_u128_wrapping_sub_1() { - let max_u128: u128 = BoundedInt::max(); - let should_be_max = u128_wrapping_sub(0_u128, 1_u128); - assert_eq(@max_u128, @should_be_max, 'Should be max u128') -} - -#[test] -fn test_u128_wrapping_sub_2() { - let max_u128_minus_two: u128 = BoundedInt::max() - 2; - let should_be_max = u128_wrapping_sub(0_u128, 3_u128); - assert_eq(@max_u128_minus_two, @should_be_max, 'Should be max u128 - 2') -} - -#[test] -fn test_u128_wrapping_sub_3() { - let max_u128_minus_899: u128 = BoundedInt::max() - 899; - let should_be_max = u128_wrapping_sub(100, 1000); - assert_eq(@max_u128_minus_899, @should_be_max, 'Should be max u128 - 899') -} - -#[test] -fn test_u128_wrapping_sub_4() { - let should_be_zero = u128_wrapping_sub(0_u128, 0_u128); - assert_eq(@should_be_zero, @0, 'Should be 0') -} - -#[test] -#[should_panic] -fn test_u128_add_overflow_1() { - 0x80000000000000000000000000000000_u128 + 0x80000000000000000000000000000000_u128; -} - -#[test] -#[should_panic] -fn test_u128_add_overflow_2() { - (0x80000000000000000000000000000000_u128 + 12_u128) + 0x80000000000000000000000000000000_u128; -} - -#[test] -#[should_panic] -fn test_u128_mul_overflow_1() { - pow_2_64() * pow_2_64(); -} - -#[test] -#[should_panic] -fn test_u128_mul_overflow_2() { - (pow_2_64() + 1_u128) * pow_2_64(); -} - -#[test] -#[should_panic] -fn test_u128_mul_overflow_3() { - 2_u128 * 0x80000000000000000000000000000000_u128; -} - -#[test] -#[should_panic(expected: ('Division by 0',))] -fn test_u128_div_by_0() { - 2_u128 / 0_u128; -} - -#[test] -#[should_panic] -fn test_u128_mod_by_0() { - 2_u128 % 0_u128; -} - -fn pow_2_127() -> u256 { - 0x80000000000000000000000000000000_u256 -} - -#[test] -fn test_u256_from_felt252() { - assert_eq(@1.into(), @1_u256, 'into 1'); - assert_eq( - @(170141183460469231731687303715884105728 * 2).into(), - @0x100000000000000000000000000000000_u256, - 'into 2**128' - ); -} - -#[test] -fn test_u256_operators() { - let max_u128 = 0xffffffffffffffffffffffffffffffff_u256; - assert_eq( - @(0x100000000000000000000000000000001 + 0x300000000000000000000000000000002), - @0x400000000000000000000000000000003_u256, - 'no Overflow' - ); - assert_eq( - @(0x180000000000000000000000000000000 + 0x380000000000000000000000000000000), - @0x500000000000000000000000000000000_u256, - 'basic Overflow' - ); - assert_eq( - @(0x400000000000000000000000000000003 - 0x100000000000000000000000000000001), - @0x300000000000000000000000000000002_u256, - 'no UF' - ); - assert_eq( - @(0x500000000000000000000000000000000 - 0x180000000000000000000000000000000), - @0x380000000000000000000000000000000_u256, - 'basic UF' - ); - assert_eq( - @(0x400000000000000000000000000000003 * 1), - @0x400000000000000000000000000000003_u256, - 'mul by 1' - ); - assert_eq( - @(0x400000000000000000000000000000003 * 2), - @0x800000000000000000000000000000006_u256, - 'mul by 2' - ); - assert_eq( - @(0x80000000000000000000000000000000 * 2), - @0x100000000000000000000000000000000_u256, - 'basic mul Overflow' - ); - assert_eq( - @(max_u128 * max_u128), - @0xfffffffffffffffffffffffffffffffe00000000000000000000000000000001_u256, - 'max_u128 * max_u128' - ); - assert_eq(@(max_u128 * 1), @max_u128, 'max_u128 * 1'); - assert_eq(@(1 * max_u128), @max_u128, '1 * max_u128'); - let v0_2: u256 = 0x000000000000000000000000000000002; - let v0_3: u256 = 0x000000000000000000000000000000003; - let v1_1: u256 = 0x100000000000000000000000000000001; - let v1_2: u256 = 0x100000000000000000000000000000002; - let v2_0: u256 = 0x200000000000000000000000000000000; - let v2_1: u256 = 0x200000000000000000000000000000001; - let v2_2: u256 = 0x200000000000000000000000000000002; - let v2_3: u256 = 0x200000000000000000000000000000003; - let v3_0: u256 = 0x300000000000000000000000000000000; - let v3_2: u256 = 0x300000000000000000000000000000002; - assert_eq(@(v1_2 | v2_2), @v3_2, '1.2|2.2==3.2'); - assert_eq(@(v2_1 | v2_2), @v2_3, '2.1|2.2==2.3'); - assert_eq(@(v2_2 | v1_2), @v3_2, '2.2|1.2==3.2'); - assert_eq(@(v2_2 | v2_1), @v2_3, '2.2|2.1==2.3'); - assert_eq(@(v1_2 & v2_2), @v0_2, '1.2&2.2==0.2'); - assert_eq(@(v2_1 & v2_2), @v2_0, '2.1&2.2==2.0'); - assert_eq(@(v2_2 & v1_2), @v0_2, '2.2&1.2==0.2'); - assert_eq(@(v2_2 & v2_1), @v2_0, '2.2&2.1==2.0'); - assert_eq(@(v1_2 ^ v2_2), @v3_0, '1.2^2.2==3.0'); - assert_eq(@(v2_1 ^ v2_2), @v0_3, '2.1^2.2==0.3'); - assert_eq(@(v2_2 ^ v1_2), @v3_0, '2.2^1.2==3.0'); - assert_eq(@(v2_2 ^ v2_1), @v0_3, '2.2^2.1==0.3'); - assert_lt(v1_2, v2_2, '1.2<2.2'); - assert_lt(v2_1, v2_2, '2.1<2.2'); - assert(!(v2_2 < v1_2), '2.2<1.2'); - assert(!(v2_2 < v2_1), '2.2<2.1'); - assert(!(v2_2 < v2_2), '2.2<2.2'); - assert_le(v1_2, v2_2, '1.2<=2.2'); - assert_le(v2_1, v2_2, '2.1<=2.2'); - assert(!(v2_2 <= v1_2), '2.2<=1.2'); - assert(!(v2_2 <= v2_1), '2.2<=2.1'); - assert_le(v2_2, v2_2, '2.2<=2.2'); - assert(!(v1_2 > v2_2), '1.2>2.2'); - assert(!(v2_1 > v2_2), '2.1>2.2'); - assert_gt(v2_2, v1_2, '2.2>1.2'); - assert_gt(v2_2, v2_1, '2.2>2.1'); - assert(!(v2_2 > v2_2), '2.2>2.2'); - assert(!(v1_2 >= v2_2), '1.2>=2.2'); - assert(!(v2_1 >= v2_2), '2.1>=2.2'); - assert_ge(v2_2, v1_2, '2.2>=1.2'); - assert_ge(v2_2, v2_1, '2.2>=2.1'); - assert_ge(v2_2, v2_2, '2.2>=2.2'); - - assert_eq(@(v3_2 / v1_1), @v0_2, 'u256 div'); - assert_eq( - @(0x400000000000000000000000000000002 / 3), - @0x155555555555555555555555555555556_u256, - 'u256 div' - ); - assert_eq(@(0x400000000000000000000000000000002 % 3), @0_u256, 'u256 mod'); - assert_eq(@(0x10000000000000000 / 0x10000000000000000), @1_u256, 'u256 div'); - assert_eq(@(0x10000000000000000 % 0x10000000000000000), @0_u256, 'u256 mod'); - assert_eq( - @(0x1000000000000000000000000000000000000000000000000 - / 0x1000000000000000000000000000000000000000000000000), - @1_u256, - 'u256 div' - ); - assert_eq( - @(0x1000000000000000000000000000000000000000000000000 % 0x1000000000000000000000000000000000000000000000000), - @0_u256, - 'u256 mod' - ); - assert_eq(@(BoundedInt::max() % 0x100000000), @0xffffffff_u256, 'u256 mod'); - assert_eq(@(BoundedInt::max() % 0x10000000000000000), @0xffffffffffffffff_u256, 'u256 mod'); - assert_eq( - @(BoundedInt::max() / 0x10000000000000000000000000000000000000000), - @0xffffffffffffffffffffffff_u256, - 'u256 div' - ); - assert_eq( - @(BoundedInt::max() / 0x1000000000000000000000000000000000000000000000000), - @0xffffffffffffffff_u256, - 'u256 div' - ); - assert_eq( - @~max_u128, - @0xffffffffffffffffffffffffffffffff00000000000000000000000000000000, - '~0x0..0f..f == 0xf..f0..0' - ); - assert_eq( - @~0xffffffffffffffffffffffffffffffff00000000000000000000000000000000, - @max_u128, - '~0xf..f0..0 == 0x0..0f..f' - ); -} - -#[test] -#[should_panic] -fn test_u256_add_overflow() { - let v = 0x8000000000000000000000000000000000000000000000000000000000000001_u256; - v + v; -} - -#[test] -#[should_panic] -fn test_u256_sub_overflow() { - 0x100000000000000000000000000000001_u256 - 0x100000000000000000000000000000002; -} - -#[test] -#[should_panic] -fn test_u256_mul_overflow_1() { - 0x100000000000000000000000000000001_u256 * 0x100000000000000000000000000000002; -} - -#[test] -#[should_panic] -fn test_u256_mul_overflow_2() { - pow_2_127() * 0x200000000000000000000000000000000; -} - -#[test] -fn test_u256_wide_mul() { - assert_eq(@u256_wide_mul(0, 0), @u512 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }, '0 * 0 != 0'); - assert_eq( - @u256_wide_mul( - 0x1001001001001001001001001001001001001001001001001001, - 0x1000100010001000100010001000100010001000100010001000100010001 - ), - @u512 { - limb0: 0x33233223222222122112111111011001, - limb1: 0x54455445544554454444443443343333, - limb2: 0x21222222322332333333433443444444, - limb3: 0x1001101111112112 - }, - 'long calculation failed' - ); -} - -#[test] -fn test_u512_safe_div_rem_by_u256() { - let zero = u512 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }; - let one = u512 { limb0: 1, limb1: 0, limb2: 0, limb3: 0 }; - let large_num = u512 { - limb0: 0x33233223222222122112111111011001, - limb1: 0x54455445544554454444443443343333, - limb2: 0x21222222322332333333433443444444, - limb3: 0x1001101111112112 - }; - let (q, r) = u512_safe_div_rem_by_u256(zero, 1_u256.try_into().unwrap()); - assert(q == zero, '0 / 1 != 0'); - assert(r == 0, '0 % 1 != 0'); - let (q, r) = u512_safe_div_rem_by_u256(one, 1_u256.try_into().unwrap()); - assert(q == one, '1 / 1 != 1'); - assert(r == 0, '1 % 1 != 0'); - let (q, r) = u512_safe_div_rem_by_u256(large_num, 1_u256.try_into().unwrap()); - assert(q == large_num, 'LARGE / 1 != LARGE'); - assert(r == 0, 'LARGE % 1 != 0'); - let (q, r) = u512_safe_div_rem_by_u256( - large_num, 0x33233223222222122112111111011001_u256.try_into().unwrap() - ); - assert( - q == u512 { - limb0: 0x365ec98ac1c2c57afaff780a20a0b2b1, - limb1: 0xf3dfa68ede27c4236ef0c6eb66a8e0a2, - limb2: 0x501e5b7ba7f4ec12, - limb3: 0 - }, - 'large div failed' - ); - assert(r == 0x1e0eb905027d0150d2618bbd71844d50, 'large rem failed'); -} - -#[test] -fn test_u512_try_into_u256() { - assert!( - u512 { limb0: 1, limb1: 2, limb2: 0, limb3: 0 } - .try_into() == Option::Some(0x200000000000000000000000000000001_u256) - ); - assert!(u512 { limb0: 1, limb1: 2, limb2: 3, limb3: 0 }.try_into() == Option::::None); - assert!(u512 { limb0: 1, limb1: 2, limb2: 0, limb3: 4 }.try_into() == Option::::None); - assert!(u512 { limb0: 1, limb1: 2, limb2: 3, limb3: 4 }.try_into() == Option::::None); -} - -#[test] -fn test_min() { - let min_u8: u8 = BoundedInt::min(); - let min_u16: u16 = BoundedInt::min(); - let min_u32: u32 = BoundedInt::min(); - let min_u64: u64 = BoundedInt::min(); - let min_u128: u128 = BoundedInt::min(); - let min_u256: u256 = BoundedInt::min(); - assert_eq(@min_u8, @0_u8, 'not zero'); - assert_eq(@min_u16, @0_u16, 'not zero'); - assert_eq(@min_u32, @0_u32, 'not zero'); - assert_eq(@min_u64, @0_u64, 'not zero'); - assert_eq(@min_u128, @0_u128, 'not zero'); - assert_eq(@min_u256, @0_u256, 'not zero'); -} - -#[test] -fn test_max() { - let max_u8: u8 = BoundedInt::max(); - let max_u16: u16 = BoundedInt::max(); - let max_u32: u32 = BoundedInt::max(); - let max_u64: u64 = BoundedInt::max(); - let max_u128: u128 = BoundedInt::max(); - let max_u256: u256 = BoundedInt::max(); - assert_eq(@max_u8, @0xff_u8, 'not max'); - assert_eq(@max_u16, @0xffff_u16, 'not max'); - assert_eq(@max_u32, @0xffffffff_u32, 'not max'); - assert_eq(@max_u64, @0xffffffffffffffff_u64, 'not max'); - assert_eq(@max_u128, @0xffffffffffffffffffffffffffffffff_u128, 'not max'); - assert_eq( - @max_u256, - @0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_u256, - 'not max' - ); -} - -#[test] -#[should_panic] -fn test_max_u8_plus_1_overflow() { - BoundedInt::max() + 1_u8; -} - -#[test] -#[should_panic] -fn test_max_u16_plus_1_overflow() { - BoundedInt::max() + 1_u16; -} - -#[test] -#[should_panic] -fn test_max_u32_plus_1_overflow() { - BoundedInt::max() + 1_u32; -} -#[test] -#[should_panic] -fn test_max_u64_plus_1_overflow() { - BoundedInt::max() + 1_u64; -} - -#[test] -#[should_panic] -fn test_max_u128_plus_1_overflow() { - BoundedInt::max() + 1_u128; -} - -#[test] -#[should_panic] -fn test_max_u256_plus_1_overflow() { - BoundedInt::max() + Into::::into(1); -} - -#[test] -fn test_default_values() { - assert_eq(@Default::default(), @0, '0 == 0'); - assert_eq(@Default::default(), @0_u8, '0 == 0'); - assert_eq(@Default::default(), @0_u16, '0 == 0'); - assert_eq(@Default::default(), @0_u32, '0 == 0'); - assert_eq(@Default::default(), @0_u64, '0 == 0'); - assert_eq(@Default::default(), @0_u128, '0 == 0'); - assert_eq(@Default::default(), @0_u256, '0 == 0'); -} - -#[test] -fn test_default_felt252dict_values() { - assert_eq(@Felt252DictValue::zero_default(), @0, '0 == 0'); - assert_eq(@Felt252DictValue::zero_default(), @0_u8, '0 == 0'); - assert_eq(@Felt252DictValue::zero_default(), @0_u16, '0 == 0'); - assert_eq(@Felt252DictValue::zero_default(), @0_u32, '0 == 0'); - assert_eq(@Felt252DictValue::zero_default(), @0_u64, '0 == 0'); - assert_eq(@Felt252DictValue::zero_default(), @0_u128, '0 == 0'); -} - -#[test] -fn test_u256_sqrt() { - assert_eq(@u256_sqrt(9.into()), @3, 'u256_sqrt(9) == 3'); - assert_eq(@u256_sqrt(10.into()), @3, 'u256_sqrt(10) == 3'); - assert_eq( - @u256_sqrt(1267650600228229401496703205376.into()), - @1125899906842624, - 'u256_sqrt(2^100) == 2^50' - ); - assert_eq( - @u256_sqrt(340282366920938463463374607431768211455.into()), - @18446744073709551615, - 'Wrong square root result.' - ); - assert_eq(@u256_sqrt(1.into()), @1, 'u256_sqrt(1) == 1'); - assert_eq(@u256_sqrt(0.into()), @0, 'u256_sqrt(0) == 0'); - - assert_eq(@u256_sqrt(BoundedInt::max()), @BoundedInt::max(), 'u256::MAX**0.5==u128::MAX'); - let (high, low) = integer::u128_wide_mul(BoundedInt::max(), BoundedInt::max()); - assert_eq(@u256_sqrt(u256 { low, high }), @BoundedInt::max(), '(u128::MAX**2)**0.5==u128::MAX'); -} - -#[test] -fn test_u256_try_into_felt252() { - assert_eq(@1_u256.try_into().unwrap(), @1_felt252, '1 == 1'_felt252); - assert_eq( - @0x800000000000011000000000000000000000000000000000000000000000000_u256.try_into().unwrap(), - @0x800000000000011000000000000000000000000000000000000000000000000_felt252, - 'P-1 == P-1'_felt252 - ); - assert_eq( - @0x800000000000010ffffffffffffffffffffffffffffffffffffffffffffffff_u256.try_into().unwrap(), - @0x800000000000010ffffffffffffffffffffffffffffffffffffffffffffffff_felt252, - 'P-2 == P-2'_felt252 - ); - let f: Option = 0x800000000000011000000000000000000000000000000000000000000000001_u256 - .try_into(); - assert(f.is_none(), 'prime is not felt252'); - let f: Option = 0x800000000000011000000000000000000000000000000000000000000000002_u256 - .try_into(); - assert(f.is_none(), 'prime+1 is not felt252'); - let f: Option = 0x800000000000011000000000000000100000000000000000000000000000001_u256 - .try_into(); - assert(f.is_none(), 'prime+2**128 is not felt252'); -} - -/// Checks if `b` is out of range of `A`. -fn is_out_of_range, +TryInto>(b: B) -> bool { - let no_a: Option = b.try_into(); - no_a.is_none() -} - -/// Checks if `SubType` is trivially castable to `SuperType`. -fn cast_subtype_valid< - SubType, - SuperType, - +Drop, - +Drop, - +Copy, - +Copy, - +BoundedInt, - +PartialEq, - +PartialEq, - +Into, - +TryInto ->() -> bool { - let max_sub: SubType = BoundedInt::max(); - let max_sub_as_super: SuperType = max_sub.into(); - let min_sub: SubType = BoundedInt::min(); - let min_sub_as_super: SuperType = min_sub.into(); - min_sub_as_super.try_into().unwrap() == min_sub - && max_sub_as_super.try_into().unwrap() == max_sub -} - -/// Checks that `A::max()` is castable to `B`, and `A::max() + 1` is in `B`s range, and not -/// castable back to `A`. -fn validate_max_strictly_contained< - A, - B, - +Drop, - +Drop, - +Copy, - +Copy, - +Add, - +BoundedInt, - +PartialEq, - +PartialEq, - +TryInto, - +TryInto, - +TryInto ->( - err: felt252 -) { - let max_a: A = BoundedInt::max(); - let max_a_as_b: B = max_a.try_into().expect(err); - assert(Option::Some(max_a) == max_a_as_b.try_into(), err); - assert(is_out_of_range::(max_a_as_b + 1.try_into().unwrap()), err); -} - -/// Checks that `A::min()` is castable to `B`, and `A::min() - 1` is in `B`s range, and not -/// castable back to `A`. -fn validate_min_strictly_contained< - A, - B, - +Drop, - +Drop, - +Copy, - +Copy, - +Sub, - +BoundedInt, - +PartialEq, - +PartialEq, - +TryInto, - +TryInto, - +TryInto ->( - err: felt252 -) { - let min_sub: A = BoundedInt::min(); - let min_sub_as_super: B = min_sub.try_into().expect(err); - assert(Option::Some(min_sub) == min_sub_as_super.try_into(), err); - assert(is_out_of_range::(min_sub_as_super - 1.try_into().unwrap()), err); -} - -/// Checks that castings from `SubType` to `SuperType` are correct around the bounds, where -/// `SubType` is strictly contained (in both bounds) in `SuperType`. -fn validate_cast_bounds_strictly_contained< - SubType, - SuperType, - +Drop, - +Drop, - +Copy, - +Copy, - +Add, - +Sub, - +BoundedInt, - +PartialEq, - +PartialEq, - +Into, - +TryInto, - +TryInto ->( - err: felt252 -) { - assert(cast_subtype_valid::(), err); - validate_min_strictly_contained::(err); - validate_max_strictly_contained::(err); -} - -/// Checks that castings from `SubType` to `SuperType` are correct around the bounds, where -/// `SubType` has the same min as `SuperType`, but has a lower max. -fn validate_cast_bounds_contained_same_min< - SubType, - SuperType, - +Drop, - +Drop, - +Copy, - +Copy, - +Add, - +Sub, - +BoundedInt, - +BoundedInt, - +PartialEq, - +PartialEq, - +Into, - +TryInto, - +TryInto ->( - err: felt252 -) { - assert(cast_subtype_valid::(), err); - assert(BoundedInt::::min().into() == BoundedInt::::min(), err); - validate_max_strictly_contained::(err); -} - -/// Checks that castings from `A` to `B` are correct around the bounds. -/// Assumes that the ordering of the bounds is: `a_min < b_min < a_max < b_max`. -fn validate_cast_bounds_overlapping< - A, - B, - +Drop, - +Drop, - +Copy, - +Copy, - +Sub, - +Add, - +BoundedInt, - +BoundedInt, - +PartialEq, - +PartialEq, - +TryInto, - +TryInto, - +TryInto, - +TryInto ->( - err: felt252 -) { - validate_min_strictly_contained::(err); - validate_max_strictly_contained::(err); -} - -#[test] -fn proper_cast() { - validate_cast_bounds_contained_same_min::('u8 u16 casts'); - validate_cast_bounds_contained_same_min::('u8 u32 casts'); - validate_cast_bounds_contained_same_min::('u8 u64 casts'); - validate_cast_bounds_contained_same_min::('u8 u128 casts'); - validate_cast_bounds_contained_same_min::('u16 u32 casts'); - validate_cast_bounds_contained_same_min::('u16 u64 casts'); - validate_cast_bounds_contained_same_min::('u16 u128 casts'); - validate_cast_bounds_contained_same_min::('u32 u64 casts'); - validate_cast_bounds_contained_same_min::('u32 u128 casts'); - validate_cast_bounds_contained_same_min::('u64 u128 casts'); - - validate_cast_bounds_strictly_contained::('u8 i16 casts'); - validate_cast_bounds_strictly_contained::('u8 i32 casts'); - validate_cast_bounds_strictly_contained::('u8 i64 casts'); - validate_cast_bounds_strictly_contained::('u8 i128 casts'); - validate_cast_bounds_strictly_contained::('u16 i32 casts'); - validate_cast_bounds_strictly_contained::('u16 i64 casts'); - validate_cast_bounds_strictly_contained::('u16 i128 casts'); - validate_cast_bounds_strictly_contained::('u32 i64 casts'); - validate_cast_bounds_strictly_contained::('u32 i128 casts'); - validate_cast_bounds_strictly_contained::('u64 i128 casts'); - - validate_cast_bounds_strictly_contained::('i8 i16 casts'); - validate_cast_bounds_strictly_contained::('i8 i32 casts'); - validate_cast_bounds_strictly_contained::('i8 i64 casts'); - validate_cast_bounds_strictly_contained::('i8 i128 casts'); - validate_cast_bounds_strictly_contained::('i16 i32 casts'); - validate_cast_bounds_strictly_contained::('i16 i64 casts'); - validate_cast_bounds_strictly_contained::('i16 i128 casts'); - validate_cast_bounds_strictly_contained::('i32 i64 casts'); - validate_cast_bounds_strictly_contained::('i32 i128 casts'); - validate_cast_bounds_strictly_contained::('i64 i128 casts'); - - validate_cast_bounds_overlapping::('i8 u8 casts'); - validate_cast_bounds_overlapping::('i8 u16 casts'); - validate_cast_bounds_overlapping::('i8 u32 casts'); - validate_cast_bounds_overlapping::('i8 u64 casts'); - validate_cast_bounds_overlapping::('i8 u128 casts'); - validate_cast_bounds_overlapping::('i16 u16 casts'); - validate_cast_bounds_overlapping::('i16 u32 casts'); - validate_cast_bounds_overlapping::('i16 u64 casts'); - validate_cast_bounds_overlapping::('i16 u128 casts'); - validate_cast_bounds_overlapping::('i32 u32 casts'); - validate_cast_bounds_overlapping::('i32 u64 casts'); - validate_cast_bounds_overlapping::('i32 u128 casts'); - validate_cast_bounds_overlapping::('i64 u64 casts'); - validate_cast_bounds_overlapping::('i64 u128 casts'); - validate_cast_bounds_overlapping::('i128 u128 casts'); -} - -#[test] -fn test_into_self_type() { - assert_eq(@0xFF_u8.into(), @0xFF_u8, 'u8 into u8'); - assert_eq(@0xFFFF_u16.into(), @0xFFFF_u16, 'u16 into u16'); - assert_eq(@0xFFFFFFFF_u32.into(), @0xFFFFFFFF_u32, 'u32 into u32'); - assert_eq(@0xFFFFFFFFFFFFFFFF_u64.into(), @0xFFFFFFFFFFFFFFFF_u64, 'u64 into u64'); - assert_eq( - @0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_u128.into(), - @0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_u128, - 'u128 into u128' - ); - assert_eq( - @u256 { low: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, high: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF } - .into(), - @u256 { high: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, low: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF }, - 'u256 into u256' - ); -} - -#[test] -#[should_panic] -fn panic_u16_u8_1() { - let _out: u8 = (0xFF_u16 + 1_u16).try_into().unwrap(); -} - -#[test] -#[should_panic] -fn panic_u16_u8_2() { - let max_u16: u16 = 0xFFFF; - let _out: u8 = max_u16.try_into().unwrap(); -} -#[test] -#[should_panic] -fn panic_u32_u8_1() { - let _out: u8 = (0xFF_u32 + 1_u32).try_into().unwrap(); -} - -#[test] -#[should_panic] -fn panic_u32_u8_2() { - let max_u32: u32 = 0xFFFFFFFF; - let _out: u8 = max_u32.try_into().unwrap(); -} -#[test] -#[should_panic] -fn panic_u64_u8_1() { - let _out: u8 = (0xFF_u64 + 1_u64).try_into().unwrap(); -} - -#[test] -#[should_panic] -fn panic_u64_u8_2() { - let max_u64: u64 = 0xFFFFFFFFFFFFFFFF; - let _out: u8 = max_u64.try_into().unwrap(); -} -#[test] -#[should_panic] -fn panic_u128_u8_1() { - let _out: u8 = (0xFF_u128 + 1_u128).try_into().unwrap(); -} - -#[test] -#[should_panic] -fn panic_u128_u8_2() { - let max_u128: u128 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; - let _out: u8 = max_u128.try_into().unwrap(); -} -#[test] -#[should_panic] -fn panic_u32_u16_1() { - let _out: u16 = (0xFFFF_u32 + 1_u32).try_into().unwrap(); -} - -#[test] -#[should_panic] -fn panic_u32_u16_2() { - let max_u32: u32 = 0xFFFFFFFF; - let _out: u16 = max_u32.try_into().unwrap(); -} -#[test] -#[should_panic] -fn panic_u64_u16_1() { - let _out: u16 = (0xFFFF_u64 + 1_u64).try_into().unwrap(); -} - -#[test] -#[should_panic] -fn panic_u64_u16_2() { - let max_u64: u64 = 0xFFFFFFFFFFFFFFFF; - let _out: u16 = max_u64.try_into().unwrap(); -} -#[test] -#[should_panic] -fn panic_u128_u16_1() { - let _out: u16 = (0xFFFF_u128 + 1_u128).try_into().unwrap(); -} - -#[test] -#[should_panic] -fn panic_u128_u16_2() { - let max_u128: u128 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; - let _out: u16 = max_u128.try_into().unwrap(); -} -#[test] -#[should_panic] -fn panic_u64_u32_1() { - let _out: u32 = (0xFFFFFFFF_u64 + 1_u64).try_into().unwrap(); -} - -#[test] -#[should_panic] -fn panic_u64_u32_2() { - let max_u64: u64 = 0xFFFFFFFFFFFFFFFF; - let _out: u32 = max_u64.try_into().unwrap(); -} - -#[test] -#[should_panic] -fn panic_u128_u32_1() { - let _out: u32 = (0xFFFFFFFF_u128 + 1_u128).try_into().unwrap(); -} - -#[test] -#[should_panic] -fn panic_u128_u32_2() { - let max_u128: u128 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; - let _out: u32 = max_u128.try_into().unwrap(); -} - -#[test] -#[should_panic] -fn panic_u128_u64_1() { - let _out: u64 = (0xFFFFFFFFFFFFFFFF_u128 + 1_u128).try_into().unwrap(); -} - -#[test] -#[should_panic] -fn panic_u128_u64_2() { - let max_u128: u128 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; - let _out: u64 = max_u128.try_into().unwrap(); -} - -#[test] -fn test_u128_byte_reverse() { - assert_eq( - @integer::u128_byte_reverse(0x000102030405060708090a0b0c0d0e0f), - @0x0f0e0d0c0b0a09080706050403020100, - 'Wrong byte reverse' - ); -} - -#[test] -fn test_i8_operators() { - assert_eq(@1_i8, @1_i8, '1 == 1'); - assert_ne(@1_i8, @2_i8, '1 != 2'); - assert_eq(@0x7f_felt252.try_into().unwrap(), @0x7f_i8, '0x7f is not i8'); - let v: Option = 0x80_felt252.try_into(); - assert(v.is_none(), '0x80 is i8'); - assert_eq(@(-0x80_felt252).try_into().unwrap(), @-0x80_i8, '-0x80 is not i8'); - let v: Option = (-0x81_felt252).try_into(); - assert(v.is_none(), '-0x81 is i8'); - assert_eq(@(1_i8 + 3_i8), @4_i8, '1 + 3 == 4'); - assert_eq(@(3_i8 + 6_i8), @9_i8, '3 + 6 == 9'); - assert_eq(@(3_i8 - 1_i8), @2_i8, '3 - 1 == 2'); - assert_eq(@(121_i8 - 21_i8), @100_i8, '121-21=100'); - assert_eq(@(-1_i8 + -3_i8), @-4_i8, '-1 + -3 == -4'); - assert_eq(@(-3_i8 + -6_i8), @-9_i8, '-3 + -6 == -9'); - assert_eq(@(-3_i8 - -1_i8), @-2_i8, '-3 - -1 == -2'); - assert_eq(@(-121_i8 - -21_i8), @-100_i8, '-121--21=-100'); - assert_eq(@(1_i8 * 3_i8), @3_i8, '1 * 3 == 3'); - assert_eq(@(2_i8 * 4_i8), @8_i8, '2 * 4 == 8'); - assert_eq(@(-1_i8 * 3_i8), @-3_i8, '-1 * 3 == 3'); - assert_eq(@(-2_i8 * 4_i8), @-8_i8, '-2 * 4 == 8'); - assert_eq(@(1_i8 * -3_i8), @-3_i8, '1 * -3 == -3'); - assert_eq(@(2_i8 * -4_i8), @-8_i8, '2 * -4 == -8'); - assert_eq(@(-1_i8 * -3_i8), @3_i8, '-1 * -3 == 3'); - assert_eq(@(-2_i8 * -4_i8), @8_i8, '-2 * -4 == 8'); - assert_lt(1_i8, 4_i8, '1 < 4'); - assert_le(1_i8, 4_i8, '1 <= 4'); - assert(!(4_i8 < 4_i8), '!(4 < 4)'); - assert_le(5_i8, 5_i8, '5 <= 5'); - assert(!(5_i8 <= 4_i8), '!(5 <= 8)'); - assert_gt(5_i8, 2_i8, '5 > 2'); - assert_ge(5_i8, 2_i8, '5 >= 2'); - assert(!(3_i8 > 3_i8), '!(3 > 3)'); - assert_ge(3_i8, 3_i8, '3 >= 3'); -} - -#[test] -#[should_panic(expected: ('i8_sub Underflow',))] -fn test_i8_sub_underflow_1() { - -0x80_i8 - 1_i8; -} - -#[test] -#[should_panic(expected: ('i8_sub Underflow',))] -fn test_i8_sub_underflow_2() { - -0x80_i8 - 3_i8; -} - -#[test] -#[should_panic(expected: ('i8_sub Underflow',))] -fn test_i8_sub_underflow_3() { - -0x7f_i8 - 3_i8; -} - -#[test] -#[should_panic(expected: ('i8_sub Underflow',))] -fn test_i8_sub_underflow_4() { - -0x32_i8 - 0x7d_i8; -} - -#[test] -#[should_panic(expected: ('i8_sub Overflow',))] -fn test_i8_sub_overflow() { - 0x32_i8 - -0x7d_i8; -} - -#[test] -#[should_panic(expected: ('i8_add Overflow',))] -fn test_i8_add_overflow_1() { - 0x40_i8 + 0x40_i8; -} - -#[test] -#[should_panic(expected: ('i8_add Overflow',))] -fn test_i8_add_overflow_2() { - 0x64_i8 + 0x1e_i8; -} - -#[test] -#[should_panic(expected: ('i8_add Underflow',))] -fn test_i8_add_underflow() { - -0x64_i8 + -0x1e_i8; -} - -#[test] -#[should_panic] -fn test_i8_mul_overflow_1() { - 0x10_i8 * 0x10_i8; -} - -#[test] -#[should_panic] -fn test_i8_mul_overflow_2() { - 0x11_i8 * 0x10_i8; -} - -#[test] -#[should_panic] -fn test_i8_mul_overflow_3() { - 2_i8 * 0x40_i8; -} - -#[test] -fn test_i16_operators() { - assert_eq(@1_i16, @1_i16, '1 == 1'); - assert_ne(@1_i16, @2_i16, '1 != 2'); - assert_eq(@0x7fff_felt252.try_into().unwrap(), @0x7fff_i16, '0x7fff is not i16'); - let v: Option = 0x8000_felt252.try_into(); - assert(v.is_none(), '0x8000 is i16'); - assert_eq(@(-0x8000_felt252).try_into().unwrap(), @-0x8000_i16, '-0x8000 is not i16'); - let v: Option = (-0x8001_felt252).try_into(); - assert(v.is_none(), '-0x8001 is i16'); - assert_eq(@(1_i16 + 3_i16), @4_i16, '1 + 3 == 4'); - assert_eq(@(3_i16 + 6_i16), @9_i16, '3 + 6 == 9'); - assert_eq(@(3_i16 - 1_i16), @2_i16, '3 - 1 == 2'); - assert_eq(@(231_i16 - 131_i16), @100_i16, '231-131=100'); - assert_eq(@(-1_i16 + -3_i16), @-4_i16, '-1 + -3 == -4'); - assert_eq(@(-3_i16 + -6_i16), @-9_i16, '-3 + -6 == -9'); - assert_eq(@(-3_i16 - -1_i16), @-2_i16, '-3 - -1 == -2'); - assert_eq(@(-231_i16 - -131_i16), @-100_i16, '-231--131=-100'); - assert_eq(@(1_i16 * 3_i16), @3_i16, '1 * 3 == 3'); - assert_eq(@(2_i16 * 4_i16), @8_i16, '2 * 4 == 8'); - assert_eq(@(-1_i16 * 3_i16), @-3_i16, '-1 * 3 == 3'); - assert_eq(@(-2_i16 * 4_i16), @-8_i16, '-2 * 4 == 8'); - assert_eq(@(1_i16 * -3_i16), @-3_i16, '1 * -3 == -3'); - assert_eq(@(2_i16 * -4_i16), @-8_i16, '2 * -4 == -8'); - assert_eq(@(-1_i16 * -3_i16), @3_i16, '-1 * -3 == 3'); - assert_eq(@(-2_i16 * -4_i16), @8_i16, '-2 * -4 == 8'); - assert_lt(1_i16, 4_i16, '1 < 4'); - assert_le(1_i16, 4_i16, '1 <= 4'); - assert(!(4_i16 < 4_i16), '!(4 < 4)'); - assert_le(5_i16, 5_i16, '5 <= 5'); - assert(!(5_i16 <= 4_i16), '!(5 <= 8)'); - assert_gt(5_i16, 2_i16, '5 > 2'); - assert_ge(5_i16, 2_i16, '5 >= 2'); - assert(!(3_i16 > 3_i16), '!(3 > 3)'); - assert_ge(3_i16, 3_i16, '3 >= 3'); -} - -#[test] -#[should_panic(expected: ('i16_sub Underflow',))] -fn test_i16_sub_underflow_1() { - -0x8000_i16 - 1_i16; -} - -#[test] -#[should_panic(expected: ('i16_sub Underflow',))] -fn test_i16_sub_underflow_2() { - -0x8000_i16 - 3_i16; -} - -#[test] -#[should_panic(expected: ('i16_sub Underflow',))] -fn test_i16_sub_underflow_3() { - -0x7fff_i16 - 3_i16; -} - -#[test] -#[should_panic(expected: ('i16_sub Underflow',))] -fn test_i16_sub_underflow_4() { - -0x3200_i16 - 0x7d00_i16; -} - -#[test] -#[should_panic(expected: ('i16_sub Overflow',))] -fn test_i16_sub_overflow() { - 0x3200_i16 - -0x7d00_i16; -} - -#[test] -#[should_panic(expected: ('i16_add Overflow',))] -fn test_i16_add_overflow_1() { - 0x4000_i16 + 0x4000_i16; -} - -#[test] -#[should_panic(expected: ('i16_add Overflow',))] -fn test_i16_add_overflow_2() { - 0x6400_i16 + 0x1e00_i16; -} - -#[test] -#[should_panic(expected: ('i16_add Underflow',))] -fn test_i16_add_underflow() { - -0x6400_i16 + -0x1e00_i16; -} - -#[test] -#[should_panic] -fn test_i16_mul_overflow_1() { - 0x1000_i16 * 0x1000_i16; -} - -#[test] -#[should_panic] -fn test_i16_mul_overflow_2() { - 0x1100_i16 * 0x1000_i16; -} - -#[test] -#[should_panic] -fn test_i16_mul_overflow_3() { - 2_i16 * 0x4000_i16; -} - -#[test] -fn test_i32_operators() { - assert_eq(@1_i32, @1_i32, '1 == 1'); - assert_ne(@1_i32, @2_i32, '1 != 2'); - assert_eq(@0x7fffffff_felt252.try_into().unwrap(), @0x7fffffff_i32, '0x7fffffff is not i32'); - let v: Option = 0x80000000_felt252.try_into(); - assert(v.is_none(), '0x80000000 is i32'); - assert_eq(@(-0x80000000_felt252).try_into().unwrap(), @-0x80000000_i32, '-0x8000 is not i32'); - let v: Option = (-0x80000001_felt252).try_into(); - assert(v.is_none(), '-0x80000001 is i32'); - assert_eq(@(1_i32 + 3_i32), @4_i32, '1 + 3 == 4'); - assert_eq(@(3_i32 + 6_i32), @9_i32, '3 + 6 == 9'); - assert_eq(@(3_i32 - 1_i32), @2_i32, '3 - 1 == 2'); - assert_eq(@(231_i32 - 131_i32), @100_i32, '231-131=100'); - assert_eq(@(-1_i32 + -3_i32), @-4_i32, '-1 + -3 == -4'); - assert_eq(@(-3_i32 + -6_i32), @-9_i32, '-3 + -6 == -9'); - assert_eq(@(-3_i32 - -1_i32), @-2_i32, '-3 - -1 == -2'); - assert_eq(@(-231_i32 - -131_i32), @-100_i32, '-231--131=-100'); - assert_eq(@(1_i32 * 3_i32), @3_i32, '1 * 3 == 3'); - assert_eq(@(2_i32 * 4_i32), @8_i32, '2 * 4 == 8'); - assert_eq(@(-1_i32 * 3_i32), @-3_i32, '-1 * 3 == 3'); - assert_eq(@(-2_i32 * 4_i32), @-8_i32, '-2 * 4 == 8'); - assert_eq(@(1_i32 * -3_i32), @-3_i32, '1 * -3 == -3'); - assert_eq(@(2_i32 * -4_i32), @-8_i32, '2 * -4 == -8'); - assert_eq(@(-1_i32 * -3_i32), @3_i32, '-1 * -3 == 3'); - assert_eq(@(-2_i32 * -4_i32), @8_i32, '-2 * -4 == 8'); - assert_lt(1_i32, 4_i32, '1 < 4'); - assert_le(1_i32, 4_i32, '1 <= 4'); - assert(!(4_i32 < 4_i32), '!(4 < 4)'); - assert_le(5_i32, 5_i32, '5 <= 5'); - assert(!(5_i32 <= 4_i32), '!(5 <= 8)'); - assert_gt(5_i32, 2_i32, '5 > 2'); - assert_ge(5_i32, 2_i32, '5 >= 2'); - assert(!(3_i32 > 3_i32), '!(3 > 3)'); - assert_ge(3_i32, 3_i32, '3 >= 3'); -} - -#[test] -#[should_panic(expected: ('i32_sub Underflow',))] -fn test_i32_sub_underflow_1() { - -0x80000000_i32 - 1_i32; -} - -#[test] -#[should_panic(expected: ('i32_sub Underflow',))] -fn test_i32_sub_underflow_2() { - -0x80000000_i32 - 3_i32; -} - -#[test] -#[should_panic(expected: ('i32_sub Underflow',))] -fn test_i32_sub_underflow_3() { - -0x7fffffff_i32 - 3_i32; -} - -#[test] -#[should_panic(expected: ('i32_sub Underflow',))] -fn test_i32_sub_underflow_4() { - -0x32000000_i32 - 0x7d000000_i32; -} - -#[test] -#[should_panic(expected: ('i32_sub Overflow',))] -fn test_i32_sub_overflow() { - 0x32000000_i32 - -0x7d000000_i32; -} - -#[test] -#[should_panic(expected: ('i32_add Overflow',))] -fn test_i32_add_overflow_1() { - 0x40000000_i32 + 0x40000000_i32; -} - -#[test] -#[should_panic(expected: ('i32_add Overflow',))] -fn test_i32_add_overflow_2() { - 0x64000000_i32 + 0x1e000000_i32; -} - -#[test] -#[should_panic(expected: ('i32_add Underflow',))] -fn test_i32_add_underflow() { - -0x64000000_i32 + -0x1e000000_i32; -} - -#[test] -#[should_panic] -fn test_i32_mul_overflow_1() { - 0x10000000_i32 * 0x10000000_i32; -} - -#[test] -#[should_panic] -fn test_i32_mul_overflow_2() { - 0x11000000_i32 * 0x10000000_i32; -} - -#[test] -#[should_panic] -fn test_i32_mul_overflow_3() { - 2_i32 * 0x40000000_i32; -} - -#[test] -fn test_i64_operators() { - assert_eq(@1_i64, @1_i64, '1 == 1'); - assert_ne(@1_i64, @2_i64, '1 != 2'); - assert_eq( - @0x7fffffffffffffff_felt252.try_into().unwrap(), - @0x7fffffffffffffff_i64, - '0x7fffffffffffffff is not i64' - ); - let v: Option = 0x8000000000000000_felt252.try_into(); - assert(v.is_none(), '0x8000000000000000 is i64'); - assert_eq( - @(-0x8000000000000000_felt252).try_into().unwrap(), - @-0x8000000000000000_i64, - '-0x8000000000000000 is not i64' - ); - let v: Option = (-0x8000000000000001_felt252).try_into(); - assert(v.is_none(), '-0x8000000000000001 is i64'); - assert_eq(@(1_i64 + 3_i64), @4_i64, '1 + 3 == 4'); - assert_eq(@(3_i64 + 6_i64), @9_i64, '3 + 6 == 9'); - assert_eq(@(3_i64 - 1_i64), @2_i64, '3 - 1 == 2'); - assert_eq(@(231_i64 - 131_i64), @100_i64, '231-131=100'); - assert_eq(@(-1_i64 + -3_i64), @-4_i64, '-1 + -3 == -4'); - assert_eq(@(-3_i64 + -6_i64), @-9_i64, '-3 + -6 == -9'); - assert_eq(@(-3_i64 - -1_i64), @-2_i64, '-3 - -1 == -2'); - assert_eq(@(-231_i64 - -131_i64), @-100_i64, '-231--131=-100'); - assert_eq(@(1_i64 * 3_i64), @3_i64, '1 * 3 == 3'); - assert_eq(@(2_i64 * 4_i64), @8_i64, '2 * 4 == 8'); - assert_eq(@(-1_i64 * 3_i64), @-3_i64, '-1 * 3 == 3'); - assert_eq(@(-2_i64 * 4_i64), @-8_i64, '-2 * 4 == 8'); - assert_eq(@(1_i64 * -3_i64), @-3_i64, '1 * -3 == -3'); - assert_eq(@(2_i64 * -4_i64), @-8_i64, '2 * -4 == -8'); - assert_eq(@(-1_i64 * -3_i64), @3_i64, '-1 * -3 == 3'); - assert_eq(@(-2_i64 * -4_i64), @8_i64, '-2 * -4 == 8'); - assert_lt(1_i64, 4_i64, '1 < 4'); - assert_le(1_i64, 4_i64, '1 <= 4'); - assert(!(4_i64 < 4_i64), '!(4 < 4)'); - assert_le(5_i64, 5_i64, '5 <= 5'); - assert(!(5_i64 <= 4_i64), '!(5 <= 8)'); - assert_gt(5_i64, 2_i64, '5 > 2'); - assert_ge(5_i64, 2_i64, '5 >= 2'); - assert(!(3_i64 > 3_i64), '!(3 > 3)'); - assert_ge(3_i64, 3_i64, '3 >= 3'); -} - -#[test] -#[should_panic(expected: ('i64_sub Underflow',))] -fn test_i64_sub_underflow_1() { - -0x8000000000000000_i64 - 1_i64; -} - -#[test] -#[should_panic(expected: ('i64_sub Underflow',))] -fn test_i64_sub_underflow_2() { - -0x8000000000000000_i64 - 3_i64; -} - -#[test] -#[should_panic(expected: ('i64_sub Underflow',))] -fn test_i64_sub_underflow_3() { - -0x7fffffffffffffff_i64 - 3_i64; -} - -#[test] -#[should_panic(expected: ('i64_sub Underflow',))] -fn test_i64_sub_underflow_4() { - -0x3200000000000000_i64 - 0x7d00000000000000_i64; -} - -#[test] -#[should_panic(expected: ('i64_sub Overflow',))] -fn test_i64_sub_overflow() { - 0x3200000000000000_i64 - -0x7d00000000000000_i64; -} - -#[test] -#[should_panic(expected: ('i64_add Overflow',))] -fn test_i64_add_overflow_1() { - 0x4000000000000000_i64 + 0x4000000000000000_i64; -} - -#[test] -#[should_panic(expected: ('i64_add Overflow',))] -fn test_i64_add_overflow_2() { - 0x6400000000000000_i64 + 0x1e00000000000000_i64; -} - -#[test] -#[should_panic(expected: ('i64_add Underflow',))] -fn test_i64_add_underflow() { - -0x6400000000000000_i64 + -0x1e00000000000000_i64; -} - -#[test] -#[should_panic] -fn test_i64_mul_overflow_1() { - 0x1000000000000000_i64 * 0x1000000000000000_i64; -} - -#[test] -#[should_panic] -fn test_i64_mul_overflow_2() { - 0x1100000000000000_i64 * 0x1000000000000000_i64; -} - -#[test] -#[should_panic] -fn test_i64_mul_overflow_3() { - 2_i64 * 0x4000000000000000_i64; -} - -#[test] -fn test_i128_operators() { - assert_eq(@1_i128, @1_i128, '1 == 1'); - assert_ne(@1_i128, @2_i128, '1 != 2'); - assert_eq( - @0x7fffffffffffffffffffffffffffffff_felt252.try_into().unwrap(), - @0x7fffffffffffffffffffffffffffffff_i128, - '0x7f..f is not i128' - ); - let v: Option = 0x80000000000000000000000000000000_felt252.try_into(); - assert(v.is_none(), '0x80..0 is i128'); - assert_eq( - @(-0x80000000000000000000000000000000_felt252).try_into().unwrap(), - @-0x80000000000000000000000000000000_i128, - '-0x80..0 is not i128' - ); - let v: Option = (-0x80000000000000000000000000000001_felt252).try_into(); - assert(v.is_none(), '-0x80..01 is i128'); - assert_eq(@(1_i128 + 3_i128), @4_i128, '1 + 3 == 4'); - assert_eq(@(3_i128 + 6_i128), @9_i128, '3 + 6 == 9'); - assert_eq(@(3_i128 - 1_i128), @2_i128, '3 - 1 == 2'); - assert_eq(@(231_i128 - 131_i128), @100_i128, '231-131=100'); - assert_eq(@(-1_i128 + -3_i128), @-4_i128, '-1 + -3 == -4'); - assert_eq(@(-3_i128 + -6_i128), @-9_i128, '-3 + -6 == -9'); - assert_eq(@(-3_i128 - -1_i128), @-2_i128, '-3 - -1 == -2'); - assert_eq(@(-231_i128 - -131_i128), @-100_i128, '-231--131=-100'); - assert_eq(@(1_i128 * 3_i128), @3_i128, '1 * 3 == 3'); - assert_eq(@(7_i128 * 0_i128), @0_i128, '7 * 0 == 0'); - assert_eq(@(2_i128 * 4_i128), @8_i128, '2 * 4 == 8'); - assert_eq(@(-1_i128 * 3_i128), @-3_i128, '-1 * 3 == -3'); - assert_eq(@(-2_i128 * 4_i128), @-8_i128, '-2 * 4 == -8'); - assert_eq(@(1_i128 * -3_i128), @-3_i128, '1 * -3 == -3'); - assert_eq(@(2_i128 * -4_i128), @-8_i128, '2 * -4 == -8'); - assert_eq(@(-1_i128 * -3_i128), @3_i128, '-1 * -3 == 3'); - assert_eq(@(-2_i128 * -4_i128), @8_i128, '-2 * -4 == 8'); - assert_eq( - @(0x800000000000000_i128 * -0x100000000000000000_i128), - @-0x80000000000000000000000000000000_i128, - 'failed MIN_I128 as mul result' - ); - assert_lt(1_i128, 4_i128, '1 < 4'); - assert_le(1_i128, 4_i128, '1 <= 4'); - assert(!(4_i128 < 4_i128), '!(4 < 4)'); - assert_le(5_i128, 5_i128, '5 <= 5'); - assert(!(5_i128 <= 4_i128), '!(5 <= 8)'); - assert_gt(5_i128, 2_i128, '5 > 2'); - assert_ge(5_i128, 2_i128, '5 >= 2'); - assert(!(3_i128 > 3_i128), '!(3 > 3)'); - assert_ge(3_i128, 3_i128, '3 >= 3'); -} - -#[test] -#[should_panic] -fn test_i128_sub_underflow_1() { - -0x80000000000000000000000000000000_i128 - 1_i128; -} - -#[test] -#[should_panic(expected: ('i128_sub Underflow',))] -fn test_i128_sub_underflow_2() { - -0x80000000000000000000000000000000_i128 - 3_i128; -} - -#[test] -#[should_panic(expected: ('i128_sub Underflow',))] -fn test_i128_sub_underflow_3() { - -0x7fffffffffffffffffffffffffffffff_i128 - 3_i128; -} - -#[test] -#[should_panic(expected: ('i128_sub Underflow',))] -fn test_i128_sub_underflow_4() { - -0x32000000000000000000000000000000_i128 - 0x7d000000000000000000000000000000_i128; -} - -#[test] -#[should_panic(expected: ('i128_sub Overflow',))] -fn test_i128_sub_overflow() { - 0x32000000000000000000000000000000_i128 - -0x7d000000000000000000000000000000_i128; -} - -#[test] -#[should_panic(expected: ('i128_add Overflow',))] -fn test_i128_add_overflow_1() { - 0x40000000000000000000000000000000_i128 + 0x40000000000000000000000000000000_i128; -} - -#[test] -#[should_panic(expected: ('i128_add Overflow',))] -fn test_i128_add_overflow_2() { - 0x64000000000000000000000000000000_i128 + 0x1e000000000000000000000000000000_i128; -} - -#[test] -#[should_panic(expected: ('i128_add Underflow',))] -fn test_i128_add_underflow() { - -0x64000000000000000000000000000000_i128 + -0x1e000000000000000000000000000000_i128; -} - -#[test] -#[should_panic] -fn test_i128_mul_overflow_1() { - 0x10000000000000000000000000000000_i128 * 0x10000000000000000000000000000000_i128; -} - -#[test] -#[should_panic] -fn test_i128_mul_overflow_2() { - 0x11000000000000000000000000000000_i128 * 0x10000000000000000000000000000000_i128; -} - -#[test] -#[should_panic] -fn test_i128_mul_overflow_3() { - 2_i128 * 0x40000000000000000000000000000000_i128; -} - -#[test] -fn test_signed_int_diff() { - assert_eq(@integer::i8_diff(3, 3).unwrap(), @0, 'i8: 3 - 3 == 0'); - assert_eq(@integer::i8_diff(4, 3).unwrap(), @1, 'i8: 4 - 3 == 1'); - assert_eq(@integer::i8_diff(3, 5).unwrap_err(), @~(2 - 1), 'i8: 3 - 5 == -2'); - assert_eq(@integer::i16_diff(3, 3).unwrap(), @0, 'i16: 3 - 3 == 0'); - assert_eq(@integer::i16_diff(4, 3).unwrap(), @1, 'i16: 4 - 3 == 1'); - assert_eq(@integer::i16_diff(3, 5).unwrap_err(), @~(2 - 1), 'i16: 3 - 5 == -2'); - assert_eq(@integer::i32_diff(3, 3).unwrap(), @0, 'i32: 3 - 3 == 0'); - assert_eq(@integer::i32_diff(4, 3).unwrap(), @1, 'i32: 4 - 3 == 1'); - assert_eq(@integer::i32_diff(3, 5).unwrap_err(), @~(2 - 1), 'i32: 3 - 5 == -2'); - assert_eq(@integer::i64_diff(3, 3).unwrap(), @0, 'i64: 3 - 3 == 0'); - assert_eq(@integer::i64_diff(4, 3).unwrap(), @1, 'i64: 4 - 3 == 1'); - assert_eq(@integer::i64_diff(3, 5).unwrap_err(), @~(2 - 1), 'i64: 3 - 5 == -2'); - assert_eq(@integer::i128_diff(3, 3).unwrap(), @0, 'i128: 3 - 3 == 0'); - assert_eq(@integer::i128_diff(4, 3).unwrap(), @1, 'i128: 4 - 3 == 1'); - assert_eq(@integer::i128_diff(3, 5).unwrap_err(), @~(2 - 1), 'i128: 3 - 5 == -2'); -} - -mod special_casts { - extern type BoundedInt; - extern fn downcast(index: T) -> Option implicits(RangeCheck) nopanic; - extern fn upcast(index: T) -> S nopanic; - - impl DropBoundedInt120_180 of Drop>; - const U128_UPPER: felt252 = 0x100000000000000000000000000000000; - type BoundedIntU128Upper = - BoundedInt<0x100000000000000000000000000000000, 0x100000000000000000000000000000000>; - const U128_MAX: felt252 = 0xffffffffffffffffffffffffffffffff; - type BoundedIntU128Max = - BoundedInt<0xffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffff>; - - /// Is `value` the equivalent value of `expected` in `T` type. - fn is_some_of(value: Option, expected: felt252) -> bool { - match value { - Option::Some(v) => upcast(v) == expected, - Option::None => false, - } - } - - /// Is `value` the equivalent value (as `felt252`) of `expected` in `T` type. - fn felt252_downcast_valid(value: felt252) -> bool { - is_some_of(downcast::(value), value) - } - - /// Is `value` the equivalent value (as `felt252`) of `expected` in `T` type. - fn downcast_invalid(value: T) -> bool { - match downcast::(value) { - Option::Some(v) => { - // Just as a drop for `v`. - upcast::<_, felt252>(v); - false - }, - Option::None => true, - } - } - - #[test] - fn test_felt252_downcasts() { - assert!(downcast_invalid::>(1)); - assert!(felt252_downcast_valid::>(0)); - assert!(downcast_invalid::>(-1)); - assert!(downcast_invalid::>(-2)); - assert!(felt252_downcast_valid::>(-1)); - assert!(downcast_invalid::>(0)); - assert!(downcast_invalid::>(119)); - assert!(felt252_downcast_valid::>(120)); - assert!(felt252_downcast_valid::>(180)); - assert!(downcast_invalid::>(181)); - assert!(downcast_invalid::(U128_MAX - 1)); - assert!(felt252_downcast_valid::(U128_MAX)); - assert!(downcast_invalid::(U128_MAX + 1)); - assert!(downcast_invalid::(U128_UPPER - 1)); - assert!(felt252_downcast_valid::(U128_UPPER)); - assert!(downcast_invalid::(U128_UPPER + 1)); - } - - // Full prime range, but where the max element is 0. - type OneMinusPToZero = - BoundedInt<-0x800000000000011000000000000000000000000000000000000000000000000, 0>; - - type OneMinusPOnly = - BoundedInt< - -0x800000000000011000000000000000000000000000000000000000000000000, - -0x800000000000011000000000000000000000000000000000000000000000000 - >; - - #[test] - fn test_bounded_int_casts() { - let minus_1 = downcast::>(-1).unwrap(); - assert!(downcast::(upcast(minus_1)).is_none()); - let zero = downcast::>(0).unwrap(); - assert!(downcast::(upcast(zero)) == Option::Some(0)); - let one_minus_p = downcast::(1).unwrap(); - assert!(downcast::(upcast(one_minus_p)).is_none()); - let v119 = downcast::>(119).unwrap(); - assert!(downcast::, BoundedInt<120, 180>>(upcast(v119)).is_none()); - let v120 = downcast::>(120).unwrap(); - assert!( - is_some_of(downcast::, BoundedInt<120, 180>>(upcast(v120)), 120) - ); - let v180 = downcast::>(180).unwrap(); - assert!( - is_some_of(downcast::, BoundedInt<120, 180>>(upcast(v180)), 180) - ); - let v181 = downcast::>(181).unwrap(); - assert!(downcast::, BoundedInt<120, 180>>(upcast(v181)).is_none()); - } -} diff --git a/corelib/src/test/keccak_test.cairo b/corelib/src/test/keccak_test.cairo deleted file mode 100644 index 6c9c6c04b..000000000 --- a/corelib/src/test/keccak_test.cairo +++ /dev/null @@ -1,201 +0,0 @@ -use starknet::SyscallResultTrait; -use core::test::test_utils::{assert_eq, assert_ne}; - -#[test] -fn test_keccak_syscall() { - let input = array![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]; - assert_eq( - @starknet::syscalls::keccak_syscall(input.span()).unwrap_syscall(), - @u256 { low: 0xec687be9c50d2218388da73622e8fdd5, high: 0xd2eb808dfba4703c528d145dfe6571af }, - 'Wrong hash value' - ); -} - -#[test] -fn test_keccak_hash() { - let res = keccak::keccak_u256s_le_inputs(array![1].span()); - assert_eq(@res.low, @0x587f7cc3722e9654ea3963d5fe8c0748, 'Wrong hash low 1'); - assert_eq(@res.high, @0xa5963aa610cb75ba273817bce5f8c48f, 'Wrong hash high 1'); - - let res = keccak::keccak_u256s_be_inputs(array![1].span()); - assert_eq(@res.low, @0x326a7e71fdcdee263b071276522d0eb1, 'Wrong hash low 2'); - assert_eq(@res.high, @0xf60cfab7e2cb9f2d73b0c2fa4a4bf40c, 'Wrong hash high 2'); - - let res = keccak::keccak_u256s_le_inputs(array![1, 2, 3, 4].span()); - assert_eq(@res.low, @0x845f8e9f5191367fb5181e74f6eb550d, 'Wrong hash low 3'); - assert_eq(@res.high, @0x17a2126cf7391a26b41c36a687090cc5, 'Wrong hash high 3'); - - let res = keccak::keccak_u256s_be_inputs(array![1, 2, 3, 4].span()); - assert_eq(@res.low, @0x6510e6fd534f267a01086462df912739, 'Wrong hash low 4'); - assert_eq(@res.high, @0x2d9982dfaf468a9ddf7101b6323aa9d5, 'Wrong hash high 4'); -} - -// Same input as in `test_keccak_hash` but as a u64 array. -#[test] -fn test_keccak_u64() { - let mut input = array![ - 0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 - ]; - - let res = keccak::cairo_keccak(ref input, 0, 0); - - assert_eq(@res.low, @0x587f7cc3722e9654ea3963d5fe8c0748, 'Wrong hash low'); - assert_eq(@res.high, @0xa5963aa610cb75ba273817bce5f8c48f, 'Wrong hash high'); -} - -#[test] -fn test_keccak_u64_full_block() { - let mut input = array![ - 0x0000000000000001, - 0x0000000000000002, - 0x0000000000000003, - 0x0000000000000004, - 0x0000000000000005, - 0x0000000000000006, - 0x0000000000000007, - 0x0000000000000008, - 0x0000000000000009, - 0x000000000000000a, - 0x000000000000000b, - 0x000000000000000c, - 0x000000000000000d, - 0x000000000000000e, - 0x000000000000000f, - 0x0000000000000010, - 0x0000000000000011 - ]; - - let res = keccak::cairo_keccak(ref input, 0, 0); - - assert_eq(@res.low, @0x5d291eebae35b254ff50ec1fc57832e8, 'Wrong hash low'); - assert_eq(@res.high, @0x210740d45b1fe2ac908a497ef45509f5, 'Wrong hash high'); -} - -#[test] -fn test_keccak_u64_full_block_minus_byte() { - let mut input = array![ - 0x0000000000000001, - 0x0000000000000002, - 0x0000000000000003, - 0x0000000000000004, - 0x0000000000000005, - 0x0000000000000006, - 0x0000000000000007, - 0x0000000000000008, - 0x0000000000000009, - 0x000000000000000a, - 0x000000000000000b, - 0x000000000000000c, - 0x000000000000000d, - 0x000000000000000e, - 0x000000000000000f, - 0x0000000000000010, - ]; - - // We must clone the array to be used in the second part, as it's modified by `cairo_keccak`. - let mut orig_array = input.clone(); - - let res = keccak::cairo_keccak(ref input, 0x12000000000011, 7); - - assert_eq(@res.low, @0xbb968836d1704bea541a8d79dcc9067c, 'Wrong hash low 1'); - assert_eq(@res.high, @0xc98592786514c87f1a1a3d567b4dcd75, 'Wrong hash high 1'); - - // With "garbage" at the end (note the `aa`), we should get the same result. - let res = keccak::cairo_keccak(ref orig_array, 0xaa12000000000011, 7); - - assert_eq(@res.low, @0xbb968836d1704bea541a8d79dcc9067c, 'Wrong hash low 2'); - assert_eq(@res.high, @0xc98592786514c87f1a1a3d567b4dcd75, 'Wrong hash high 2'); -} - -#[test] -fn test_keccak_u64_full_block_minus_word() { - let mut input = array![ - 0x0000000000000001, - 0x0000000000000002, - 0x0000000000000003, - 0x0000000000000004, - 0x0000000000000005, - 0x0000000000000006, - 0x0000000000000007, - 0x0000000000000008, - 0x0000000000000009, - 0x000000000000000a, - 0x000000000000000b, - 0x000000000000000c, - 0x000000000000000d, - 0x000000000000000e, - 0x000000000000000f, - 0x0000000000000010, - ]; - - let res = keccak::cairo_keccak(ref input, 0, 0); - - assert_eq(@res.low, @0xfd9895001ee22e79b59c7997b3618a01, 'Wrong hash low'); - assert_eq(@res.high, @0x6851f2dbbfb3bfadff94db3ad476164f, 'Wrong hash high'); -} - -#[test] -fn test_keccak_u64_full_block_minus_word_minus_byte() { - let mut input = array![ - 0x0000000000000001, - 0x0000000000000002, - 0x0000000000000003, - 0x0000000000000004, - 0x0000000000000005, - 0x0000000000000006, - 0x0000000000000007, - 0x0000000000000008, - 0x0000000000000009, - 0x000000000000000a, - 0x000000000000000b, - 0x000000000000000c, - 0x000000000000000d, - 0x000000000000000e, - 0x000000000000000f, - ]; - - // We must clone the array to be used in the second part, as it's modified by `cairo_keccak`. - let mut orig_array = input.clone(); - - let res = keccak::cairo_keccak(ref input, 0x11000000000010, 7); - - assert_eq(@res.low, @0x2cc6d33d8630a63c428d9cf38a89568b, 'Wrong hash low'); - assert_eq(@res.high, @0xdd7e11698dc8b37323c854a53abcd330, 'Wrong hash high'); - - // With "garbage" at the end (note the `aa`), we should get the same result. - let res = keccak::cairo_keccak(ref orig_array, 0xaa11000000000010, 7); - - assert_eq(@res.low, @0x2cc6d33d8630a63c428d9cf38a89568b, 'Wrong hash low 2'); - assert_eq(@res.high, @0xdd7e11698dc8b37323c854a53abcd330, 'Wrong hash high 2'); -} - -#[test] -fn test_keccak_u64_full_block_minus_3_words_minus_4_bytes() { - let mut input = array![ - 0x0000000000000001, - 0x0000000000000002, - 0x0000000000000003, - 0x0000000000000004, - 0x0000000000000005, - 0x0000000000000006, - 0x0000000000000007, - 0x0000000000000008, - 0x0000000000000009, - 0x000000000000000a, - 0x000000000000000b, - 0x000000000000000c, - 0x000000000000000d - ]; - - // We must clone the array to be used in the second part, as it's modified by `cairo_keccak`. - let mut orig_array = input.clone(); - - let res = keccak::cairo_keccak(ref input, 0x11000010, 4); - assert_eq(@res.low, @0x43ccdbe17ae03b02b308ebe4a23c4cc9, 'Wrong hash low 1'); - assert_eq(@res.high, @0xf3cc56e9bd860f83e3e3bc69919b176a, 'Wrong hash high 1'); - - // With "garbage" at the end (note the `aa`s), we should get the same result. - let res = keccak::cairo_keccak(ref orig_array, 0xaaaaaaaa11000010, 4); - assert_eq(@res.low, @0x43ccdbe17ae03b02b308ebe4a23c4cc9, 'Wrong hash low 2'); - assert_eq(@res.high, @0xf3cc56e9bd860f83e3e3bc69919b176a, 'Wrong hash high 2'); -} diff --git a/corelib/src/test/math_test.cairo b/corelib/src/test/math_test.cairo deleted file mode 100644 index 741131c6b..000000000 --- a/corelib/src/test/math_test.cairo +++ /dev/null @@ -1,123 +0,0 @@ -use core::option::OptionTrait; -use core::math; - -#[test] -fn test_egcd() { - let (g, s, t, sub_direction) = math::egcd::(68, 16); - assert(g == 4, 'g != 4'); - assert(s == 1, 's != 1'); - assert(t == 4, 't != 4'); - assert(sub_direction, 'sub_direction is wrong'); - assert(1 * 68 - 4 * 16 == 4, 'Sanity check failed'); - - let (g, s, t, sub_direction) = math::egcd::(240, 46); - assert(g == 2, 'g != 2'); - assert(s == 9, 's != 9'); - assert(t == 47, 't != 47'); - assert(!sub_direction, 'sub_direction is wrong'); - assert(47 * 46 - 9 * 240 == 2, 'Sanity check failed'); - - let (g, s, t, sub_direction) = math::egcd::(50, 17); - assert(g == 1, 'g != 1'); - assert(s == 1, 's != 1'); - assert(t == 3, 't != 3'); - assert(!sub_direction, 'sub_direction is wrong'); - assert(3 * 17 - 1 * 50 == 1, 'Sanity check failed'); - - let (g, s, t, sub_direction) = math::egcd::(5, 15); - assert(g == 5, 'g != 5'); - assert(s == 1, 's != 1'); - assert(t == 0, 't != 0'); - assert(sub_direction, 'sub_direction is wrong'); - assert(1 * 5 - 0 * 15 == 5, 'Sanity check failed'); - - let (g, s, t, sub_direction) = math::egcd::(1, 1); - assert(g == 1, 'g != 1'); - assert(s == 0, 's != 0'); - assert(t == 1, 't != 1'); - assert(!sub_direction, 'sub_direction is wrong'); - assert(1 * 1 - 0 * 1 == 1, 'Sanity check failed'); -} - -#[test] -fn test_inv_mod() { - assert(math::inv_mod(5, 24) == Option::Some(5_u256), 'inv_mov(5, 24) != 5'); - assert(math::inv_mod(29, 24) == Option::Some(5_u128), 'inv_mov(29, 24) != 5'); - assert(math::inv_mod(1, 24) == Option::Some(1_u16), 'inv_mov(1, 24) != 1'); - assert(math::inv_mod(1, 5) == Option::Some(1_u32), 'inv_mov(1, 5) != 1'); - assert(math::inv_mod(8, 24) == Option::::None, 'inv_mov(8, 24) != None'); - assert(math::inv_mod(1, 1) == Option::Some(0_usize), 'inv_mov(1, 1) != 0'); - assert(math::inv_mod(7, 1) == Option::Some(0_usize), 'inv_mov(7, 1) != 0'); -} - -#[test] -fn test_u256_div_mod_n() { - assert(math::u256_div_mod_n(6, 2, 7) == Option::Some(3), '6 / 2 != 3 (7)'); - assert(math::u256_div_mod_n(5, 1, 7) == Option::Some(5), '5 / 1 != 5 (7)'); - assert(math::u256_div_mod_n(1, 1, 7) == Option::Some(1), '1 / 1 != 1 (7)'); - assert(math::u256_div_mod_n(7, 2, 13) == Option::Some(10), '7 / 2 != 10 (13)'); - assert(math::u256_div_mod_n(0, 3, 13) == Option::Some(0), '0 / 3 != 0 (13)'); - assert(math::u256_div_mod_n(4, 3, 6).is_none(), '4 / 3 == None (6)'); - assert(math::u256_div_mod_n(5, 4, 6).is_none(), '5 / 4 == None (6)'); - assert(math::u256_div_mod_n(2, 8, 4).is_none(), '2 / 8 == None (4)'); - assert( - math::u256_div_mod_n( - 0xfa855081cc80656250605b2ecd7958ba4f0aa6799053da0d68bf76f2484decc6, - 0xe8e94a59a951af1b4c8cbd45fb8d01c1dd946de2533e3ad18845f9dbb6d12f4f, - 0xa3db605888ac3cd19e70c5b52220ad693566b996ef078e907578fec7758dabc9 - ) == Option::Some(0x8e70aea916ee4b782a0da9c18083ed9d867148a703615a2a88d0e7fddd4c900d), - 'Random large values 1' - ); - assert( - math::u256_div_mod_n( - 0x759426f1c0ba213b6378196b5091f5fa48f49f1d0cecfb00a7d59a51be35f609, - 0x57ff2c2e0900fce82331e396a71787a837783cca8145538eb32cb4b52104a3be, - 0xcb514e4d4672d8f1d952c0312afb5baae86121aa5817030d8439ce759295a029 - ) == Option::Some(0x7c9d22b40f98075c0bfd674d546bc77d775dcf021d30b88afb099834dffa951b), - 'Random large values 2' - ); -} - -#[test] -fn test_u256_inv_mod() { - assert(math::u256_inv_mod(5, 24).unwrap().into() == 5_u256, 'inv_mov(5, 24) != 5'); - assert(math::u256_inv_mod(29, 24).unwrap().into() == 5_u256, 'inv_mov(29, 24) != 5'); - assert(math::u256_inv_mod(1, 24).unwrap().into() == 1_u256, 'inv_mov(1, 24) != 1'); - assert(math::u256_inv_mod(1, 5).unwrap().into() == 1_u256, 'inv_mov(1, 5) != 1'); - assert(math::u256_inv_mod(8, 24).is_none(), 'inv_mov(8, 24) != None'); - assert(math::u256_inv_mod(1, 1).is_none(), 'inv_mov(1, 1) != None'); - assert(math::u256_inv_mod(7, 1).is_none(), 'inv_mov(7, 1) != None'); - assert(math::u256_inv_mod(0, 1).is_none(), 'inv_mov(0, 1) != None'); - assert(math::u256_inv_mod(0, 7).is_none(), 'inv_mov(0, 7) != None'); - assert(math::u256_inv_mod(3, 6).is_none(), 'inv_mod(3, 6) != None'); - assert(math::u256_inv_mod(4, 6).is_none(), 'inv_mod(4, 6) != None'); - assert(math::u256_inv_mod(8, 4).is_none(), 'inv_mod(8, 4) != None'); - assert( - math::u256_inv_mod( - 0xea9195982bd472e30e5146ad7cb0acd954cbc75032a298ac73234b6b05e28cc1, - 0x4075f980fab77a3fde536dbaae600f5ea1540e01837dcec64c1f379613aa4d18 - ) - .is_none(), - 'Random 1' - ); - assert( - math::u256_inv_mod( - 0x85ef555d7a0aa34019c138defc40a1d3683dc1caa505bff286dd8069a28a2e4c, - 0xd71e5a5f4a4d1af45e703f9e13d1305ce149313037956247ad5edfe3e81d6353 - ) - .is_none(), - 'Random 2' - ); - let large_gcd = 0x63f7a7326f84cfca7738923db2b6d6c1b1b; - assert( - math::u256_inv_mod( - large_gcd * 0x51e28b744cc00edfb6bbbe6a9, - (large_gcd * 0xc09497df4aa02be7fd25f10d3).try_into().unwrap() - ) - .is_none(), - 'gcd ~ 2**140' - ); - let very_large_gcd: NonZero<_> = - 0x74c5ef92be07ee4ad43ae8ca337390e4a5dfdbf4f1a5f09cdf412ab7ce343503; - assert(math::u256_inv_mod(very_large_gcd.into(), very_large_gcd).is_none(), 'gcd ~ 2**256'); -} diff --git a/corelib/src/test/nullable_test.cairo b/corelib/src/test/nullable_test.cairo deleted file mode 100644 index 22c0fbcb9..000000000 --- a/corelib/src/test/nullable_test.cairo +++ /dev/null @@ -1,31 +0,0 @@ -use core::test::test_utils::{assert_eq, assert_ne}; -use core::nullable::null; - -#[test] -fn test_nullable_felt252s() { - let x = 10; - let nullable_x = NullableTrait::new(x); - assert(!nullable_x.is_null(), 'nullable_x.is_null() true'); - assert_eq(@nullable_x.deref(), @x, '*&x != x'); - let y = 11; - let nullable_y = NullableTrait::new(y); - assert(!nullable_y.is_null(), 'nullable_y.is_null() true'); - assert_eq(@nullable_y.deref(), @y, '*&y != y'); - let null: Nullable = null(); - assert(null.is_null(), 'null.is_null() false'); -} - -// Testing `u256` as a test for objects of size larger than 1. -#[test] -fn test_nullable_u256() { - let x: u256 = 10; - let nullable_x = NullableTrait::new(x); - assert(!nullable_x.is_null(), 'nullable_x.is_null() true'); - assert_eq(@nullable_x.deref(), @x, '*&x != x'); - let y: u256 = 11; - let nullable_y = NullableTrait::new(y); - assert(!nullable_y.is_null(), 'nullable_y.is_null() true'); - assert_eq(@nullable_y.deref(), @y, '*&y != y'); - let null: Nullable = null(); - assert(null.is_null(), 'null.is_null() false'); -} diff --git a/corelib/src/test/num_test.cairo b/corelib/src/test/num_test.cairo deleted file mode 100644 index c332cda14..000000000 --- a/corelib/src/test/num_test.cairo +++ /dev/null @@ -1,237 +0,0 @@ -use core::num::traits::BitSize; -use core::num::traits::{ - OverflowingAdd, OverflowingSub, OverflowingMul, WrappingAdd, WrappingSub, WrappingMul -}; -use core::integer::BoundedInt; - - -#[test] -fn test_bit_size() { - assert!(BitSize::::bits() == 8); - assert!(BitSize::::bits() == 16); - assert!(BitSize::::bits() == 32); - assert!(BitSize::::bits() == 64); - assert!(BitSize::::bits() == 128); - assert!(BitSize::::bits() == 256); - assert!(BitSize::::bits() == 8); - assert!(BitSize::::bits() == 16); - assert!(BitSize::::bits() == 32); - assert!(BitSize::::bits() == 64); - assert!(BitSize::::bits() == 128); - assert!(BitSize::::bits() == 248); -} - -// Overflowing tests - -#[test] -fn tests_overflowing_add_unsigned_integers() { - assert_eq!(1_u8.overflowing_add(2), (3, false)); - assert_eq!(BoundedInt::::max().overflowing_add(1), (0, true)); - assert_eq!(1_u16.overflowing_add(2), (3, false)); - assert_eq!(BoundedInt::::max().overflowing_add(1), (0, true)); - assert_eq!(1_u32.overflowing_add(2), (3, false)); - assert_eq!(BoundedInt::::max().overflowing_add(1), (0, true)); - assert_eq!(1_u64.overflowing_add(2), (3, false)); - assert_eq!(BoundedInt::::max().overflowing_add(1), (0, true)); - assert_eq!(1_u128.overflowing_add(2), (3, false)); - assert_eq!(BoundedInt::::max().overflowing_add(1), (0, true)); - assert_eq!(1_u256.overflowing_add(2), (3, false)); - assert_eq!(BoundedInt::::max().overflowing_add(1), (0, true)); -} - -#[test] -fn test_overflowing_add_positive_signed_integers() { - assert!(1_i8.overflowing_add(2) == (3, false)); - assert!(BoundedInt::::max().overflowing_add(1) == (-0x80, true)); - assert!(1_i16.overflowing_add(2) == (3, false)); - assert!(BoundedInt::::max().overflowing_add(1) == (-0x8000, true)); - assert!(1_i32.overflowing_add(2) == (3, false)); - assert!(BoundedInt::::max().overflowing_add(1) == (-0x80000000, true)); - assert!(1_i64.overflowing_add(2) == (3, false)); - assert!(BoundedInt::::max().overflowing_add(1) == (-0x8000000000000000, true)); - assert!(1_i128.overflowing_add(2) == (3, false)); - assert!( - BoundedInt::::max().overflowing_add(1) == (-0x80000000000000000000000000000000, true) - ); -} - -#[test] -fn test_overflowing_add_negative_signed_integers() { - assert!((-1_i8).overflowing_add(-2) == (-3, false)); - assert!(BoundedInt::::min().overflowing_add(-1) == (0x7f, true)); - assert!((-1_i16).overflowing_add(-2) == (-3, false)); - assert!(BoundedInt::::min().overflowing_add(-1) == (0x7fff, true)); - assert!((-1_i32).overflowing_add(-2) == (-3, false)); - assert!(BoundedInt::::min().overflowing_add(-1) == (0x7fffffff, true)); - assert!((-1_i64).overflowing_add(-2) == (-3, false)); - assert!(BoundedInt::::min().overflowing_add(-1) == (0x7fffffffffffffff, true)); - assert!((-1_i128).overflowing_add(-2) == (-3, false)); - assert!( - BoundedInt::::min().overflowing_add(-1) == (0x7fffffffffffffffffffffffffffffff, true) - ); -} - -fn test_overflowing_sub_unsigned_integers() { - assert_eq!(3_u8.overflowing_sub(2), (1, false)); - assert_eq!(0_u8.overflowing_sub(1), (BoundedInt::::max(), true)); - assert_eq!(3_u16.overflowing_sub(2), (1, false)); - assert_eq!(0_u16.overflowing_sub(1), (BoundedInt::::max(), true)); - assert_eq!(3_u32.overflowing_sub(2), (1, false)); - assert_eq!(0_u32.overflowing_sub(1), (BoundedInt::::max(), true)); - assert_eq!(3_u64.overflowing_sub(2), (1, false)); - assert_eq!(0_u64.overflowing_sub(1), (BoundedInt::::max(), true)); - assert_eq!(3_u128.overflowing_sub(2), (1, false)); - assert_eq!(0_u128.overflowing_sub(1), (BoundedInt::::max(), true)); - assert_eq!(3_u256.overflowing_sub(2), (1, false)); - assert_eq!(0_u256.overflowing_sub(1), (BoundedInt::::max(), true)); -} - -#[test] -fn test_overflowing_sub_positive_signed_integers() { - assert!(3_i8.overflowing_sub(2) == (1, false)); - assert!(BoundedInt::::min().overflowing_sub(1) == (BoundedInt::::max(), true)); - assert!(3_i16.overflowing_sub(2) == (1, false)); - assert!(BoundedInt::::min().overflowing_sub(1) == (BoundedInt::::max(), true)); - assert!(3_i32.overflowing_sub(2) == (1, false)); - assert!(BoundedInt::::min().overflowing_sub(1) == (BoundedInt::::max(), true)); - assert!(3_i64.overflowing_sub(2) == (1, false)); - assert!(BoundedInt::::min().overflowing_sub(1) == (BoundedInt::::max(), true)); - assert!(3_i128.overflowing_sub(2) == (1, false)); - assert!(BoundedInt::::min().overflowing_sub(1) == (BoundedInt::::max(), true)); -} - -#[test] -fn test_overflowing_sub_negative_signed_integers() { - assert!((-3_i8).overflowing_sub(-2) == (-1, false)); - assert!(BoundedInt::::max().overflowing_sub(-1) == (BoundedInt::::min(), true)); - assert!((-3_i16).overflowing_sub(-2) == (-1, false)); - assert!(BoundedInt::::max().overflowing_sub(-1) == (BoundedInt::::min(), true)); - assert!((-3_i32).overflowing_sub(-2) == (-1, false)); - assert!(BoundedInt::::max().overflowing_sub(-1) == (BoundedInt::::min(), true)); - assert!((-3_i64).overflowing_sub(-2) == (-1, false)); - assert!(BoundedInt::::max().overflowing_sub(-1) == (BoundedInt::::min(), true)); - assert!((-3_i128).overflowing_sub(-2) == (-1, false)); - assert!(BoundedInt::::max().overflowing_sub(-1) == (BoundedInt::::min(), true)); -} - -#[test] -fn test_overflowing_mul_unsigned_integers() { - assert_eq!(2_u8.overflowing_mul(3), (6, false)); - assert_eq!(BoundedInt::::max().overflowing_mul(2), (BoundedInt::::max() - 1, true)); - assert_eq!(2_u16.overflowing_mul(3), (6, false)); - assert_eq!(BoundedInt::::max().overflowing_mul(2), (BoundedInt::::max() - 1, true)); - assert_eq!(2_u32.overflowing_mul(3), (6, false)); - assert_eq!(BoundedInt::::max().overflowing_mul(2), (BoundedInt::::max() - 1, true)); - assert_eq!(2_u64.overflowing_mul(3), (6, false)); - assert_eq!(BoundedInt::::max().overflowing_mul(2), (BoundedInt::::max() - 1, true)); - assert_eq!(2_u128.overflowing_mul(3), (6, false)); - assert_eq!(BoundedInt::::max().overflowing_mul(2), (BoundedInt::::max() - 1, true)); - assert_eq!(2_u256.overflowing_mul(3), (6, false)); - assert_eq!(BoundedInt::::max().overflowing_mul(2), (BoundedInt::::max() - 1, true)); -} - -// Wrapping tests - -#[test] -fn tests_wrapping_add_unsigned_integers() { - assert_eq!(1_u8.wrapping_add(2), 3); - assert_eq!(BoundedInt::::max().wrapping_add(1), 0); - assert_eq!(1_u16.wrapping_add(2), 3); - assert_eq!(BoundedInt::::max().wrapping_add(1), 0); - assert_eq!(1_u32.wrapping_add(2), 3); - assert_eq!(BoundedInt::::max().wrapping_add(1), 0); - assert_eq!(1_u64.wrapping_add(2), 3); - assert_eq!(BoundedInt::::max().wrapping_add(1), 0); - assert_eq!(1_u128.wrapping_add(2), 3); - assert_eq!(BoundedInt::::max().wrapping_add(1), 0); - assert_eq!(1_u256.wrapping_add(2), 3); - assert_eq!(BoundedInt::::max().wrapping_add(1), 0); -} - -#[test] -fn test_wrapping_add_positive_signed_integers() { - assert!(1_i8.wrapping_add(2) == 3); - assert!(BoundedInt::::max().wrapping_add(1) == -0x80); - assert!(1_i16.wrapping_add(2) == 3); - assert!(BoundedInt::::max().wrapping_add(1) == -0x8000); - assert!(1_i32.wrapping_add(2) == 3); - assert!(BoundedInt::::max().wrapping_add(1) == -0x80000000); - assert!(1_i64.wrapping_add(2) == 3); - assert!(BoundedInt::::max().wrapping_add(1) == -0x8000000000000000); - assert!(1_i128.wrapping_add(2) == 3); - assert!(BoundedInt::::max().wrapping_add(1) == -0x80000000000000000000000000000000); -} - -#[test] -fn test_wrapping_add_negative_signed_integers() { - assert!((-1_i8).wrapping_add(-2) == -3); - assert!(BoundedInt::::min().wrapping_add(-1) == 0x7f); - assert!((-1_i16).wrapping_add(-2) == -3); - assert!(BoundedInt::::min().wrapping_add(-1) == 0x7fff); - assert!((-1_i32).wrapping_add(-2) == -3); - assert!(BoundedInt::::min().wrapping_add(-1) == 0x7fffffff); - assert!((-1_i64).wrapping_add(-2) == -3); - assert!(BoundedInt::::min().wrapping_add(-1) == 0x7fffffffffffffff); - assert!((-1_i128).wrapping_add(-2) == -3); - assert!(BoundedInt::::min().wrapping_add(-1) == 0x7fffffffffffffffffffffffffffffff); -} - -#[test] -fn test_wrapping_sub_unsigned_integers() { - assert_eq!(3_u8.wrapping_sub(2), 1); - assert_eq!(0_u8.wrapping_sub(1), BoundedInt::::max()); - assert_eq!(3_u16.wrapping_sub(2), 1); - assert_eq!(0_u16.wrapping_sub(1), BoundedInt::::max()); - assert_eq!(3_u32.wrapping_sub(2), 1); - assert_eq!(0_u32.wrapping_sub(1), BoundedInt::::max()); - assert_eq!(3_u64.wrapping_sub(2), 1); - assert_eq!(0_u64.wrapping_sub(1), BoundedInt::::max()); - assert_eq!(3_u128.wrapping_sub(2), 1); - assert_eq!(0_u128.wrapping_sub(1), BoundedInt::::max()); - assert_eq!(3_u256.wrapping_sub(2), 1); - assert_eq!(0_u256.wrapping_sub(1), BoundedInt::::max()); -} - -#[test] -fn test_wrapping_sub_positive_signed_integers() { - assert!(3_i8.wrapping_sub(2) == 1); - assert!(BoundedInt::::min().wrapping_sub(1) == BoundedInt::::max()); - assert!(3_i16.wrapping_sub(2) == 1); - assert!(BoundedInt::::min().wrapping_sub(1) == BoundedInt::::max()); - assert!(3_i32.wrapping_sub(2) == 1); - assert!(BoundedInt::::min().wrapping_sub(1) == BoundedInt::::max()); - assert!(3_i64.wrapping_sub(2) == 1); - assert!(BoundedInt::::min().wrapping_sub(1) == BoundedInt::::max()); - assert!(3_i128.wrapping_sub(2) == 1); - assert!(BoundedInt::::min().wrapping_sub(1) == BoundedInt::::max()); -} - -#[test] -fn test_wrapping_sub_negative_signed_integers() { - assert!((-3_i8).wrapping_sub(-2) == -1); - assert!(BoundedInt::::max().wrapping_sub(-1) == BoundedInt::::min()); - assert!((-3_i16).wrapping_sub(-2) == -1); - assert!(BoundedInt::::max().wrapping_sub(-1) == BoundedInt::::min()); - assert!((-3_i32).wrapping_sub(-2) == -1); - assert!(BoundedInt::::max().wrapping_sub(-1) == BoundedInt::::min()); - assert!((-3_i64).wrapping_sub(-2) == -1); - assert!(BoundedInt::::max().wrapping_sub(-1) == BoundedInt::::min()); - assert!((-3_i128).wrapping_sub(-2) == -1); - assert!(BoundedInt::::max().wrapping_sub(-1) == BoundedInt::::min()); -} - -#[test] -fn test_wrapping_mul_unsigned_integers() { - assert_eq!(2_u8.wrapping_mul(3), 6); - assert_eq!(BoundedInt::::max().wrapping_mul(2), BoundedInt::::max() - 1); - assert_eq!(2_u16.wrapping_mul(3), 6); - assert_eq!(BoundedInt::::max().wrapping_mul(2), BoundedInt::::max() - 1); - assert_eq!(2_u32.wrapping_mul(3), 6); - assert_eq!(BoundedInt::::max().wrapping_mul(2), BoundedInt::::max() - 1); - assert_eq!(2_u64.wrapping_mul(3), 6); - assert_eq!(BoundedInt::::max().wrapping_mul(2), BoundedInt::::max() - 1); - assert_eq!(2_u128.wrapping_mul(3), 6); - assert_eq!(BoundedInt::::max().wrapping_mul(2), BoundedInt::::max() - 1); - assert_eq!(2_u256.wrapping_mul(3), 6); - assert_eq!(BoundedInt::::max().wrapping_mul(2), BoundedInt::::max() - 1); -} diff --git a/corelib/src/test/panics_test.cairo b/corelib/src/test/panics_test.cairo deleted file mode 100644 index 5115fd35b..000000000 --- a/corelib/src/test/panics_test.cairo +++ /dev/null @@ -1,146 +0,0 @@ -use core::byte_array::BYTE_ARRAY_MAGIC; -use core::{panics, panic_with_felt252}; - -#[test] -#[should_panic(expected: 'short_string')] -fn test_panic_with_short_string() { - panic_with_felt252('short_string'); -} - -#[test] -#[should_panic(expected: 1)] -fn test_panic_with_felt252() { - panic_with_felt252(1); -} - -#[test] -#[should_panic(expected: "")] -fn test_panic_with_byte_array_empty() { - let ba: ByteArray = Default::default(); - panics::panic_with_byte_array(@ba); -} - -#[test] -#[should_panic(expected: "error")] -fn test_panic_with_byte_array_short() { - let ba: ByteArray = "error"; - panics::panic_with_byte_array(@ba); -} - -#[test] -#[should_panic(expected: "long error with more than 31 characters")] -fn test_panic_with_byte_array_long() { - let ba: ByteArray = "long error with more than 31 characters"; - panics::panic_with_byte_array(@ba); -} - -#[test] -#[should_panic(expected: "long err\0r with more than 31 characters")] -fn test_panic_with_byte_array_null_in_full_word() { - let mut ba: ByteArray = "long err"; - ba.append_byte(0); - let ba2: ByteArray = "r with more than 31 characters"; - ba.append(@ba2); - panics::panic_with_byte_array(@ba); -} - -#[test] -#[should_panic(expected: "long error with more than 31 character\0s")] -fn test_panic_with_byte_array_null_in_pending() { - let mut ba: ByteArray = "long error with more than 31 character"; - ba.append_byte(0); - let ba2: ByteArray = "s"; - ba.append(@ba2); - panics::panic_with_byte_array(@ba); -} - -#[test] -#[should_panic(expected: "\0error")] -fn test_panic_with_byte_array_null_in_beginning() { - let mut ba: ByteArray = ""; - ba.append_byte(0); - let ba2: ByteArray = "error"; - ba.append(@ba2); - panics::panic_with_byte_array(@ba); -} - -#[test] -#[should_panic(expected: ("error", 11, "hello", 5, 'short_string'))] -fn test_panic_with_stacked_errors() { - let mut error = array![]; - let ba: ByteArray = "error"; - error.append(BYTE_ARRAY_MAGIC); - ba.serialize(ref error); - - error.append(11); - - let ba: ByteArray = "hello"; - error.append(BYTE_ARRAY_MAGIC); - ba.serialize(ref error); - - error.append(5); - error.append('short_string'); - - panic(error); -} - -#[test] -#[should_panic( - expected: ( - 0x46a6158a16a947e5916b2a2ca68501a45e93d7110e81aa2d6438b1c57c879a3, // BYTE_ARRAY_MAGIC - 1, - 0x161616161616161616161616161616161616161616161616161616161616161, - 0, - 0 - ) -)] -fn test_panic_with_byte_array_invalid_full_word() { - // This is a serialized ByteArray, but the full word is an invalid short string (> 2^248). - let mut error = array![ - BYTE_ARRAY_MAGIC, - 1, // A single full word. - 0x161616161616161616161616161616161616161616161616161616161616161, // The invalid full word. - 0, - 0 // pending byte is empty. - ]; - panic(error); -} - -#[test] -#[should_panic( - expected: ( - 0x46a6158a16a947e5916b2a2ca68501a45e93d7110e81aa2d6438b1c57c879a3, // BYTE_ARRAY_MAGIC - 0, - 'aa', - 1 - ) -)] -fn test_panic_with_byte_array_invalid_pending_word() { - // This is a serialized ByteArray, but the pending word length < the actual data in the pending - // word. - let mut error = array![ - BYTE_ARRAY_MAGIC, - 0, // No full words. - 'aa', - 1 // pending word length. Smaller than the actual data in the pending word. - ]; - panic(error); -} - -#[test] -#[should_panic(expected: "")] -fn test_panic_macro_empty() { - panic!() -} - -#[test] -#[should_panic(expected: "basic")] -fn test_panic_macro_basic_string() { - panic!("basic") -} - -#[test] -#[should_panic(expected: "some_format(1)")] -fn test_panic_macro_with_input() { - panic!("some_format({})", 1) -} diff --git a/corelib/src/test/plugins_test.cairo b/corelib/src/test/plugins_test.cairo deleted file mode 100644 index 95ccf8f8c..000000000 --- a/corelib/src/test/plugins_test.cairo +++ /dev/null @@ -1,146 +0,0 @@ -use core::test::test_utils::assert_eq; - -#[derive(Copy, Debug, Drop, Serde, PartialEq)] -enum EnumForSerde { - A, - B: u32, - C: u64, -} - -#[derive(Drop, Debug, Default, PartialEq)] -struct StructForDefault { - a: felt252, - b: u256, - c: bool -} - -#[derive(Drop, Debug, Default, PartialEq)] -enum EnumForDefault { - A: felt252, - B: u256, - #[default] - C: StructForDefault, -} - -#[test] -fn test_derive_serde_enum() { - let a = EnumForSerde::A; - let b = EnumForSerde::B(1); - let c = EnumForSerde::C(2); - let mut output = Default::default(); - a.serialize(ref output); - a.serialize(ref output); - c.serialize(ref output); - b.serialize(ref output); - a.serialize(ref output); - let mut serialized = output.span(); - assert_eq( - @Serde::::deserialize(ref serialized).expect('failed to read'), - @a, - 'expected a' - ); - assert_eq( - @Serde::::deserialize(ref serialized).expect('failed to read'), - @a, - 'expected a' - ); - assert_eq( - @Serde::::deserialize(ref serialized).expect('failed to read'), - @c, - 'expected c' - ); - assert_eq( - @Serde::::deserialize(ref serialized).expect('failed to read'), - @b, - 'expected b' - ); - assert_eq( - @Serde::::deserialize(ref serialized).expect('failed to read'), - @a, - 'expected a' - ); - assert(serialized.is_empty(), 'expected empty'); -} - -#[test] -fn test_derive_default_struct() { - assert_eq!(Default::default(), StructForDefault { a: 0, b: 0, c: false }); -} - -#[test] -fn test_derive_default_enum() { - assert_eq!(Default::default(), EnumForDefault::C(StructForDefault { a: 0, b: 0, c: false })); -} - -#[derive(Copy, Debug, Drop, Serde, PartialEq)] -enum LongEnum5 { - A, - B, - C, - D, - E -} -#[derive(Copy, Debug, Drop, Serde, PartialEq)] -enum longEnum10 { - A, - B, - C, - D, - E, - F, - G, - H, - I, - J -} -#[derive(Copy, Debug, Drop, Serde, PartialEq)] -enum longEnum15 { - A, - B, - C, - D, - E, - F, - G, - H, - I, - J, - K, - L, - M, - N, - O -} - - -#[test] -fn test_long_enum5_deserialize() { - let x = LongEnum5::E; - let mut output = Default::default(); - x.serialize(ref output); - let mut serialized = output.span(); - assert_eq( - @Serde::::deserialize(ref serialized).expect('failed to read'), @x, 'expected E' - ); -} -#[test] -fn test_long_enum10_deserialize() { - let x = longEnum10::J; - let mut output = Default::default(); - x.serialize(ref output); - let mut serialized = output.span(); - assert_eq( - @Serde::::deserialize(ref serialized).expect('failed to read'), @x, 'expected J' - ); -} -#[test] -fn test_long_enum15_deserialize() { - let x = longEnum15::O; - let mut output = Default::default(); - x.serialize(ref output); - let mut serialized = output.span(); - assert_eq( - @Serde::::deserialize(ref serialized).expect('failed to read'), @x, 'expected O' - ); -} - diff --git a/corelib/src/test/print_test.cairo b/corelib/src/test/print_test.cairo deleted file mode 100644 index 161d10a8e..000000000 --- a/corelib/src/test/print_test.cairo +++ /dev/null @@ -1,131 +0,0 @@ -use core::byte_array::BYTE_ARRAY_MAGIC; -use core::debug::{PrintTrait, print_byte_array_as_string}; - -#[ignore] -#[test] -fn test_prints() { - // Valid short string. - 'hello'.print(); - - // felt252 - 1.print(); - - // Valid string with < 31 characters (no full words). - let x: ByteArray = "short, but string"; - print_byte_array_as_string(@x); - - // Valid string with > 31 characters (with a full word). - let x: ByteArray = "This is a long string with more than 31 characters."; - print_byte_array_as_string(@x); - - // Valid string as an array. - let x = array![ - BYTE_ARRAY_MAGIC, - 1, // A single full word. - 'This is a long string with more', - ' than 31 characters.', - 20 // pending word length. Bigger than the actual data in the pending word. - ]; - x.print(); - - // Only magic. - let x = array![BYTE_ARRAY_MAGIC]; - x.print(); - - // num_full_words > usize. - let x = array![BYTE_ARRAY_MAGIC, 0x100000000]; - x.print(); - - // Not enough data after num_full_words. - let x = array![BYTE_ARRAY_MAGIC, 0]; - x.print(); - - // Not enough full words. - let x = array![BYTE_ARRAY_MAGIC, 1, 0, 0]; - x.print(); - - // Too much data in full word. - let x = array![ - BYTE_ARRAY_MAGIC, - 1, // A single full word. - 0x161616161616161616161616161616161616161616161616161616161616161, // The invalid full word. - 0, - 0 // pending byte is empty. - ]; - x.print(); - - // num_pending_bytes > usize. - let x = array![BYTE_ARRAY_MAGIC, 0, 0, 0x100000000]; - x.print(); - - // "Not enough" data in pending_word (nulls in the beginning). - let x = array![ - BYTE_ARRAY_MAGIC, - 0, // No full words. - 'a', - 2 // pending word length. Bigger than the actual data in the pending word. - ]; - x.print(); - - // Too much data in pending_word. - let x = array![ - BYTE_ARRAY_MAGIC, - 0, // No full words. - 'aa', - 1 // pending word length. Smaller than the actual data in the pending word. - ]; - x.print(); - - // Valid string with Null. - let mut x: ByteArray = "Hello"; - x.append_byte(0); // '\0' - let suffix: ByteArray = "world"; - x.append(@suffix); - print_byte_array_as_string(@x); - - // Valid string with a non printable character. - let mut x: ByteArray = "Hello"; - x.append_byte(0x11); // Non printable character. - let suffix: ByteArray = "world"; - x.append(@suffix); - print_byte_array_as_string(@x); - - // Valid string with a newline. - let mut x: ByteArray = "Hello"; - x.append_byte(0xA); // '\n' - let suffix: ByteArray = "world"; - x.append(@suffix); - print_byte_array_as_string(@x); - - // Multiple values: (felt, string, short_string, felt) - let x = array![0x9999, BYTE_ARRAY_MAGIC, 0, 'hello', 5, 'world', 0x8888]; - x.print(); -} - -#[ignore] -#[test] -fn test_print_macro() { - // With a ByteArray. - let ba: ByteArray = "hello"; - print!("{}", ba); - - // With a felt252. - print!("{}", 97_felt252); - - // With an integer. - print!("{}", 97_usize); -} - -#[ignore] -#[test] -fn test_println_macro() { - // With a ByteArray. - let ba: ByteArray = "hello"; - println!("{}", ba); - - // With a felt252. - println!("{}", 97_felt252); - - // With an integer. - println!("{}", 97_usize); -} diff --git a/corelib/src/test/result_test.cairo b/corelib/src/test/result_test.cairo deleted file mode 100644 index 4d4fa83bb..000000000 --- a/corelib/src/test/result_test.cairo +++ /dev/null @@ -1,125 +0,0 @@ -use core::result::{Result, ResultTraitImpl}; - -#[test] -fn test_result_ok_expect() { - let result: Result = Result::Ok(42); - assert(result.expect('') == 42, 'result_ok_expect'); -} - -#[test] -#[should_panic(expected: ('err msg',))] -fn test_result_err_expect() { - let result: Result = Result::Err('no'); - result.expect('err msg'); -} - -#[test] -fn test_result_ok_unwrap() { - let result: Result = Result::Ok(42); - assert(result.unwrap() == 42, 'result_ok_unwrap'); -} - -#[test] -#[should_panic(expected: ('Result::unwrap failed.',))] -fn test_result_err_unwrap() { - let result: Result = Result::Err('no'); - result.unwrap(); -} - -#[test] -fn test_result_ok_unwrap_or() { - let result: Result = Result::Ok(42); - assert(result.unwrap_or(0) == 42, 'result_ok_unwrap_or'); -} - -#[test] -fn test_result_err_unwrap_or() { - let result: Result = Result::Err('no'); - assert(result.unwrap_or(0) == 0, 'result_err_unwrap_or'); -} - -#[test] -fn test_result_ok_unwrap_or_default() { - let result: Result = Result::Ok(42); - assert(result.unwrap_or_default() == 42, 'result_ok_unwrap_or_default'); -} - -#[test] -fn test_result_err_unwrap_or_default() { - let result: Result = Result::Err('no'); - assert(result.unwrap_or_default() == 0, 'result_err_unwrap_or_default'); -} - -#[test] -#[should_panic(expected: ('err msg',))] -fn test_result_ok_expect_err() { - let result: Result = Result::Ok(42); - result.expect_err('err msg'); -} - -#[test] -fn test_result_err_expect_err() { - let result: Result = Result::Err('no'); - assert(result.expect_err('') == 'no', 'result_err_expect_err'); -} - -#[test] -#[should_panic(expected: ('Result::unwrap_err failed.',))] -fn test_result_ok_unwrap_err() { - let result: Result = Result::Ok(42); - result.unwrap_err(); -} - -#[test] -fn test_result_err_unwrap_err() { - let result: Result = Result::Err('no'); - assert(result.unwrap_err() == 'no', 'result_err_unwrap_err'); -} - -#[test] -fn test_result_ok_is_ok() { - let result: Result = Result::Ok(42); - assert(result.is_ok(), 'result_ok_is_ok'); -} - -#[test] -fn test_result_err_is_ok() { - let result: Result = Result::Err('no'); - assert(!result.is_ok(), 'result_err_is_ok'); -} - -#[test] -fn test_result_ok_is_err() { - let result: Result = Result::Ok(42); - assert(!result.is_err(), 'result_ok_is_err'); -} - -#[test] -fn test_result_err_is_err() { - let result: Result = Result::Err('no'); - assert(result.is_err(), 'result_err_is_err'); -} - -#[test] -fn test_result_ok_into_is_err() { - let result: Result = Result::Ok(42); - assert(!result.into_is_err(), 'result_ok_into_is_err'); -} - -#[test] -fn test_result_err_into_is_err() { - let result: Result = Result::Err('no'); - assert(result.into_is_err(), 'result_err_into_is_err'); -} - -#[test] -fn test_result_ok_into_is_ok() { - let result: Result = Result::Ok(42); - assert(result.into_is_ok(), 'result_ok_into_is_ok'); -} - -#[test] -fn test_result_err_into_is_ok() { - let result: Result = Result::Err('no'); - assert(!result.into_is_ok(), 'result_err_into_is_ok'); -} diff --git a/corelib/src/test/secp256k1_test.cairo b/corelib/src/test/secp256k1_test.cairo deleted file mode 100644 index 2fb253be8..000000000 --- a/corelib/src/test/secp256k1_test.cairo +++ /dev/null @@ -1,139 +0,0 @@ -use starknet::{ - eth_address::U256IntoEthAddress, EthAddress, secp256k1::Secp256k1Impl, SyscallResultTrait -}; -use starknet::secp256_trait::{ - Signature, recover_public_key, Secp256PointTrait, signature_from_vrs, is_valid_signature -}; -use starknet::secp256k1::{Secp256k1Point, Secp256k1PointImpl}; -use starknet::eth_signature::verify_eth_signature; - -#[test] -fn test_secp256k1_recover_public_key() { - let y_parity = true; - let (msg_hash, signature, expected_public_key_x, expected_public_key_y, _) = - get_message_and_signature( - :y_parity - ); - let public_key = recover_public_key::(msg_hash, signature).unwrap(); - let (x, y) = public_key.get_coordinates().unwrap_syscall(); - assert(expected_public_key_x == x, 'recover failed 1'); - assert(expected_public_key_y == y, 'recover failed 2'); - - let y_parity = false; - let (msg_hash, signature, expected_public_key_x, expected_public_key_y, _) = - get_message_and_signature( - :y_parity - ); - let public_key = recover_public_key::(msg_hash, signature).unwrap(); - let (x, y) = public_key.get_coordinates().unwrap_syscall(); - assert(expected_public_key_x == x, 'recover failed 3'); - assert(expected_public_key_y == y, 'recover failed 4'); -} - -#[test] -fn test_signature_from_vrs() { - let v = 27; - let r = 1; - let s = 2; - let signature = signature_from_vrs(v, r, s); - - assert(signature == Signature { r, s, y_parity: false }, 'Wrong result'); -} - -/// Returns a golden valid message hash and its signature, for testing. -fn get_message_and_signature(y_parity: bool) -> (u256, Signature, u256, u256, EthAddress) { - let msg_hash = 0xe888fbb4cf9ae6254f19ba12e6d9af54788f195a6f509ca3e934f78d7a71dd85; - let r = 0x4c8e4fbc1fbb1dece52185e532812c4f7a5f81cf3ee10044320a0d03b62d3e9a; - let s = 0x4ac5e5c0c0e8a4871583cc131f35fb49c2b7f60e6a8b84965830658f08f7410c; - - let (public_key_x, public_key_y) = if y_parity { - ( - 0xa9a02d48081294b9bb0d8740d70d3607feb20876964d432846d9b9100b91eefd, - 0x18b410b5523a1431024a6ab766c89fa5d062744c75e49efb9925bf8025a7c09e - ) - } else { - ( - 0x57a910a2a58ef7d57f452e1f6ea7ee0080789091de946b0ca6e5c6af2c8ff5c8, - 0x249d233d0d21f35db55ce852edbd340d31e92ea4d591886149ca5d89911331ac - ) - }; - let eth_address = 0x767410c1bb448978bd42b984d7de5970bcaf5c43_u256.into(); - - (msg_hash, Signature { r, s, y_parity }, public_key_x, public_key_y, eth_address) -} - -#[test] -fn test_verify_eth_signature() { - let y_parity = true; - let (msg_hash, signature, _expected_public_key_x, _expected_public_key_y, eth_address) = - get_message_and_signature( - :y_parity - ); - verify_eth_signature(:msg_hash, :signature, :eth_address); -} - -#[test] -#[should_panic(expected: ('Invalid signature',))] -fn test_verify_eth_signature_wrong_eth_address() { - let y_parity = true; - let (msg_hash, signature, _expected_public_key_x, _expected_public_key_y, eth_address) = - get_message_and_signature( - :y_parity - ); - let eth_address = (eth_address.into() + 1).try_into().unwrap(); - verify_eth_signature(:msg_hash, :signature, :eth_address); -} - -#[test] -#[should_panic(expected: ('Signature out of range',))] -fn test_verify_eth_signature_overflowing_signature_r() { - let y_parity = true; - let (msg_hash, mut signature, _expected_public_key_x, _expected_public_key_y, eth_address) = - get_message_and_signature( - :y_parity - ); - signature.r = Secp256k1Impl::get_curve_size() + 1; - verify_eth_signature(:msg_hash, :signature, :eth_address); -} - -#[test] -#[should_panic(expected: ('Signature out of range',))] -fn test_verify_eth_signature_overflowing_signature_s() { - let y_parity = true; - let (msg_hash, mut signature, _expected_public_key_x, _expected_public_key_y, eth_address) = - get_message_and_signature( - :y_parity - ); - signature.s = Secp256k1Impl::get_curve_size() + 1; - verify_eth_signature(:msg_hash, :signature, :eth_address); -} - -#[test] -#[available_gas(100000000)] -fn test_verify_signature() { - let (msg_hash, signature, public_key_x, public_key_y, _) = get_message_and_signature(false); - - let public_key = Secp256k1Impl::secp256_ec_new_syscall(public_key_x, public_key_y) - .unwrap_syscall() - .unwrap(); - - let is_valid = is_valid_signature::< - Secp256k1Point - >(msg_hash, signature.r, signature.s, public_key); - assert(is_valid, 'Signature should be valid'); -} - -#[test] -#[available_gas(100000000)] -fn test_verify_signature_invalid_signature() { - let (msg_hash, signature, public_key_x, public_key_y, _) = get_message_and_signature(false); - - let public_key = Secp256k1Impl::secp256_ec_new_syscall(public_key_x, public_key_y) - .unwrap_syscall() - .unwrap(); - - let is_valid = is_valid_signature::< - Secp256k1Point - >(msg_hash, signature.r + 1, signature.s, public_key); - assert(!is_valid, 'Signature should be invalid'); -} diff --git a/corelib/src/test/secp256r1_test.cairo b/corelib/src/test/secp256r1_test.cairo deleted file mode 100644 index 325e93d83..000000000 --- a/corelib/src/test/secp256r1_test.cairo +++ /dev/null @@ -1,92 +0,0 @@ -use starknet::{secp256r1::Secp256r1Impl, SyscallResultTrait}; -use starknet::secp256_trait::{recover_public_key, Secp256PointTrait, Signature, is_valid_signature}; -use starknet::secp256r1::{Secp256r1Point, Secp256r1PointImpl}; -use core::test::test_utils::assert_eq; - -#[test] -fn test_secp256r1_recover_public_key() { - let (msg_hash, signature, expected_public_key_x, expected_public_key_y, _) = - get_message_and_signature(); - let public_key = recover_public_key::(msg_hash, signature).unwrap(); - let (x, y) = public_key.get_coordinates().unwrap_syscall(); - assert(expected_public_key_x == x, 'recover failed 1'); - assert(expected_public_key_y == y, 'recover failed 2'); -} - - -/// Returns a golden valid message hash and its signature, for testing. -fn get_message_and_signature() -> (u256, Signature, u256, u256, Secp256r1Point) { - // msg = "" - // public key: (0x04aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad5, - // 0x0087d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d) - let msg_hash = 0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855; - let r = 0xb292a619339f6e567a305c951c0dcbcc42d16e47f219f9e98e76e09d8770b34a; - let s = 0x177e60492c5a8242f76f07bfe3661bde59ec2a17ce5bd2dab2abebdf89a62e2; - - let (public_key_x, public_key_y) = ( - 0x04aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad5, - 0x0087d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d - ); - - let public_key = Secp256r1Impl::secp256_ec_new_syscall(public_key_x, public_key_y) - .unwrap_syscall() - .unwrap(); - - (msg_hash, Signature { r, s, y_parity: true }, public_key_x, public_key_y, public_key) -} - -#[test] -#[available_gas(100000000)] -fn test_verify_signature() { - let (msg_hash, signature, _, _, public_key) = get_message_and_signature(); - let is_valid = is_valid_signature::< - Secp256r1Point - >(msg_hash, signature.r, signature.s, public_key); - assert(is_valid, 'Signature should be valid'); -} - -#[test] -#[available_gas(100000000)] -fn test_verify_signature_invalid_signature() { - let (msg_hash, signature, _, _, public_key) = get_message_and_signature(); - let is_valid = is_valid_signature::< - Secp256r1Point - >(msg_hash, signature.r + 1, signature.s, public_key); - assert(!is_valid, 'Signature should be invalid'); -} - -#[test] -#[available_gas(100000000)] -fn test_verify_signature_overflowing_signature_r() { - let (msg_hash, mut signature, _, _, public_key) = get_message_and_signature(); - let is_valid = is_valid_signature::< - Secp256r1Point - >(msg_hash, Secp256r1Impl::get_curve_size() + 1, signature.s, public_key); - assert(!is_valid, 'Signature out of range'); -} - -#[test] -#[available_gas(100000000)] -fn test_verify_signature_overflowing_signature_s() { - let (msg_hash, mut signature, _, _, public_key) = get_message_and_signature(); - let is_valid = is_valid_signature::< - Secp256r1Point - >(msg_hash, signature.r, Secp256r1Impl::get_curve_size() + 1, public_key); - assert(!is_valid, 'Signature out of range'); -} - - -#[test] -fn test_recover_public_key_y_even() { - let x: u256 = 0x502a43ce77c6f5c736a82f847fa95f8c2d483fe223b12b91047d83258a958b0f; - let _y: u256 = 0xdb0a2e6710c71ba80afeb3abdf69d306ce729c7704f4ddf2eaaf0b76209fe1b0; - let r: u256 = 0x7380df4a623c5c2259a5e5f5b225d7265a9e24b3a13c101d1afddcf29e3cf8b2; - let s: u256 = 0x0d131afacdd17a4ea1b544bb3ade677ff8accbe7830e15b9c225e6031155946a; - let y_parity = false; - let message_hash: u256 = 0x28c7fff9aef4847a82cd64280434712a5b49205831b60eea6e70614077e672eb; - let recovered = recover_public_key::(message_hash, Signature { r, s, y_parity }) - .unwrap(); - let (recovered_x, _recovered_y) = recovered.get_coordinates().unwrap_syscall(); - - assert_eq(@recovered_x, @x, 'Signature is not valid'); -} diff --git a/corelib/src/test/test_utils.cairo b/corelib/src/test/test_utils.cairo deleted file mode 100644 index cd808a1e4..000000000 --- a/corelib/src/test/test_utils.cairo +++ /dev/null @@ -1,29 +0,0 @@ -#[inline] -pub fn assert_eq>(a: @T, b: @T, err_code: felt252) { - assert(a == b, err_code); -} - -#[inline] -pub fn assert_ne>(a: @T, b: @T, err_code: felt252) { - assert(a != b, err_code); -} - -#[inline] -pub fn assert_le>(a: T, b: T, err_code: felt252) { - assert(a <= b, err_code); -} - -#[inline] -pub fn assert_lt>(a: T, b: T, err_code: felt252) { - assert(a < b, err_code); -} - -#[inline] -pub fn assert_ge>(a: T, b: T, err_code: felt252) { - assert(a >= b, err_code); -} - -#[inline] -pub fn assert_gt>(a: T, b: T, err_code: felt252) { - assert(a > b, err_code); -} diff --git a/corelib/src/test/testing_test.cairo b/corelib/src/test/testing_test.cairo deleted file mode 100644 index 917f2106c..000000000 --- a/corelib/src/test/testing_test.cairo +++ /dev/null @@ -1,126 +0,0 @@ -use core::test::test_utils::assert_gt; - -#[test] -#[should_panic(expected: ('panic_with_felt252()',))] -fn test_panic_with_felt252() { - // No semicolon here: Missing implementation for core::traits::Drop:: - core::panic_with_felt252('panic_with_felt252()') -} - -#[test] -#[should_panic(expected: 'assert(false)')] -fn test_assert_false() { - assert(false, 'assert(false)'); -} - -#[test] -fn test_assert_true() { - assert(true, 'assert(true)'); -} - -#[test] -#[should_panic(expected: "assert(false)")] -fn test_assert_macro_false() { - assert!(false, "assert(false)"); -} - -#[test] -fn test_assert_macro_true() { - assert!(true, "assert(true)"); -} - -#[test] -fn test_assert_ne_with_description() { - assert_ne!(1, 2, "Description"); -} - -#[test] -fn test_assert_ne_no_description() { - assert_ne!(1, 2); -} - -#[test] -fn test_assert_lt_with_description() { - assert_lt!(1_u8, 2_u8, "Description"); -} - -#[test] -fn test_assert_lt_no_description() { - assert_lt!(1_u8, 2_u8); -} - -#[test] -fn test_assert_le_with_description() { - assert_le!(1_u8, 2_u8, "Description"); - assert_le!(1_u8, 1_u8, "Description"); -} - -#[test] -fn test_assert_le_no_description() { - assert_le!(1_u8, 2_u8); - assert_le!(1_u8, 1_u8); -} - -#[test] -fn test_assert_gt_with_description() { - assert_gt!(2_u8, 1_u8, "Description"); -} - -#[test] -fn test_assert_gt_no_description() { - assert_gt!(2_u8, 1_u8); -} - -#[test] -fn test_assert_ge_with_description() { - assert_ge!(2_u8, 1_u8, "Description"); - assert_ge!(2_u8, 2_u8, "Description"); -} - -#[test] -fn test_assert_ge_no_description() { - assert_ge!(2_u8, 1_u8); - assert_ge!(2_u8, 2_u8); -} - -#[test] -#[should_panic(expected: "assertion failed: `false`.")] -fn test_assert_macro_no_input() { - assert!(false); -} - -#[test] -#[should_panic(expected: "assertion `1 == 2` failed: Description -1: 1 -2: 2")] -fn test_assert_eq_with_description() { - assert_eq!(1, 2, "Description"); -} - -#[test] -#[should_panic(expected: "assertion `1 == 2` failed: 1 != 2 -1: 1 -2: 2")] -fn test_assert_eq_with_formatted_description() { - assert_eq!(1, 2, "{} != {}", 1, 2); -} - -#[test] -#[should_panic(expected: "assertion `1 == 2` failed. -1: 1 -2: 2")] -fn test_assert_eq_no_description() { - assert_eq!(1, 2); -} - -#[test] -#[available_gas(static)] -fn test_get_available_gas_no_gas_supply() { - assert_eq!(core::testing::get_available_gas(), 0) -} - -#[test] -#[available_gas(10000)] -fn test_get_available_gas_with_gas_supply() { - assert_gt(core::testing::get_available_gas(), 5000, 'high amount of gas used') -} diff --git a/corelib/src/test/to_byte_array_test.cairo b/corelib/src/test/to_byte_array_test.cairo deleted file mode 100644 index 8d6f8149b..000000000 --- a/corelib/src/test/to_byte_array_test.cairo +++ /dev/null @@ -1,249 +0,0 @@ -use core::test::test_utils::assert_eq; -use core::to_byte_array::{FormatAsByteArray, AppendFormattedToByteArray}; - -#[test] -fn test_to_string_hex() { - let hex_base: NonZero = 16_u8.try_into().unwrap(); - - let expected_string = "0"; - let serialized = 0_u8.format_as_byte_array(hex_base); - assert_eq(@serialized, @expected_string, 'Bad hex representation of 0'); - - let expected_string = "a"; - let serialized = 0xa_u8.format_as_byte_array(hex_base); - assert_eq(@serialized, @expected_string, 'Bad hex representation of 10'); - - let expected_string = "6f"; - let serialized = 0x6f_u8.format_as_byte_array(hex_base); - assert_eq(@serialized, @expected_string, 'Bad hex representation of 111'); - - let expected_string = "ff"; - let serialized = 0xff_u8.format_as_byte_array(hex_base); - assert_eq(@serialized, @expected_string, 'Bad hex representation of 255'); - - // Other uint types: - let expected_string = "6f"; - let serialized = 0x6f_u16.format_as_byte_array(base: 16_u16.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad u16 hex representation'); - let serialized = 0x6f_u32.format_as_byte_array(base: 16_u32.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad u32 hex representation'); - let serialized = 0x6f_u64.format_as_byte_array(base: 16_u64.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad u64 hex representation'); - let serialized = 0x6f_u128.format_as_byte_array(base: 16_u128.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad u128 hex representation'); - let serialized = 0x6f_u256.format_as_byte_array(base: 16_u256.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad u256 hex representation'); - let serialized = 0x6f_felt252.format_as_byte_array(base: 16.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad felt252 hex representation'); -} -#[test] -fn test_to_string_dec() { - let dec_base: NonZero = 10_u8.try_into().unwrap(); - - let expected_string = "0"; - let serialized = 0_u8.format_as_byte_array(dec_base); - assert_eq(@serialized, @expected_string, 'Bad dec representation of 0'); - - let expected_string = "10"; - let serialized = 10_u8.format_as_byte_array(dec_base); - assert_eq(@serialized, @expected_string, 'Bad dec representation of 10'); - - let expected_string = "111"; - let serialized = 111_u8.format_as_byte_array(dec_base); - assert_eq(@serialized, @expected_string, 'Bad dec representation of 111'); - - let expected_string = "255"; - let serialized = 255_u8.format_as_byte_array(dec_base); - assert_eq(@serialized, @expected_string, 'Bad dec representation of 255'); - - // Other uint types: - let expected_string = "111"; - let serialized = 111_u16.format_as_byte_array(base: 10_u16.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad u16 dec representation'); - let serialized = 111_u32.format_as_byte_array(base: 10_u32.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad u32 dec representation'); - let serialized = 111_u64.format_as_byte_array(base: 10_u64.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad u64 dec representation'); - let serialized = 111_u128.format_as_byte_array(base: 10_u128.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad u128 dec representation'); - let serialized = 111_u256.format_as_byte_array(base: 10_u256.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad u256 dec representation'); - let serialized = 111_felt252.format_as_byte_array(base: 10.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad felt252 dec representation'); -} - -#[test] -fn test_to_string_oct() { - let oct_base: NonZero = 8_u8.try_into().unwrap(); - - let expected_string = "0"; - let serialized = 0_u8.format_as_byte_array(oct_base); - assert_eq(@serialized, @expected_string, 'Bad oct representation of 0'); - - let expected_string = "12"; - let serialized = 10_u8.format_as_byte_array(oct_base); - assert_eq(@serialized, @expected_string, 'Bad oct representation of 10'); - - let expected_string = "157"; - let serialized = 111_u8.format_as_byte_array(oct_base); - assert_eq(@serialized, @expected_string, 'Bad oct representation of 111'); - - let expected_string = "377"; - let serialized = 255_u8.format_as_byte_array(oct_base); - assert_eq(@serialized, @expected_string, 'Bad oct representation of 255'); - - // Other uint types: - let expected_string = "157"; - let serialized = 111_u16.format_as_byte_array(base: 8_u16.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad u16 oct representation'); - let serialized = 111_u32.format_as_byte_array(base: 8_u32.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad u32 oct representation'); - let serialized = 111_u64.format_as_byte_array(base: 8_u64.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad u64 oct representation'); - let serialized = 111_u128.format_as_byte_array(base: 8_u128.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad u128 oct representation'); - let serialized = 111_u256.format_as_byte_array(base: 8_u256.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad u256 oct representation'); - let serialized = 111_felt252.format_as_byte_array(base: 8.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad felt252 oct representation'); -} - -#[test] -fn test_to_string_bin() { - let bin_base: NonZero = 2_u8.try_into().unwrap(); - - let expected_string = "0"; - let serialized = 0_u8.format_as_byte_array(bin_base); - assert_eq(@serialized, @expected_string, 'Bad bin representation of 0'); - - let expected_string = "1010"; - let serialized = 10_u8.format_as_byte_array(bin_base); - assert_eq(@serialized, @expected_string, 'Bad bin representation of 10'); - - let expected_string = "1101111"; - let serialized = 111_u8.format_as_byte_array(bin_base); - assert_eq(@serialized, @expected_string, 'Bad bin representation of 111'); - - let expected_string = "11111111"; - let serialized = 255_u8.format_as_byte_array(bin_base); - assert_eq(@serialized, @expected_string, 'Bad bin representation of 255'); - - // Other uint types: - let expected_string = "1101111"; - let serialized = 111_u16.format_as_byte_array(base: 2_u16.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad u16 bin representation'); - let serialized = 111_u32.format_as_byte_array(base: 2_u32.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad u32 bin representation'); - let serialized = 111_u64.format_as_byte_array(base: 2_u64.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad u64 bin representation'); - let serialized = 111_u128.format_as_byte_array(base: 2_u128.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad u128 bin representation'); - let serialized = 111_u256.format_as_byte_array(base: 2_u256.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad u256 bin representation'); - let serialized = 111_felt252.format_as_byte_array(base: 2.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad felt252 bin representation'); -} - -#[test] -fn test_to_string_base7() { - let base7: NonZero = 7_u8.try_into().unwrap(); - - let expected_string = "0"; - let serialized = 0_u8.format_as_byte_array(base7); - assert_eq(@serialized, @expected_string, 'Bad b7 representation of 0'); - - let expected_string = "13"; - let serialized = 10_u8.format_as_byte_array(base7); - assert_eq(@serialized, @expected_string, 'Bad b7 representation of 10'); - - let expected_string = "216"; - let serialized = 111_u8.format_as_byte_array(base7); - assert_eq(@serialized, @expected_string, 'Bad b7 representation of 111'); - - let expected_string = "513"; - let serialized = 255_u8.format_as_byte_array(base7); - assert_eq(@serialized, @expected_string, 'Bad b7 representation of 255'); - - // Other uint types: - let expected_string = "216"; - let serialized = 111_u16.format_as_byte_array(base: 7_u16.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad u16 b7 representation'); - let serialized = 111_u32.format_as_byte_array(base: 7_u32.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad u32 b7 representation'); - let serialized = 111_u64.format_as_byte_array(base: 7_u64.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad u64 b7 representation'); - let serialized = 111_u128.format_as_byte_array(base: 7_u128.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad u128 b7 representation'); - let serialized = 111_u256.format_as_byte_array(base: 7_u256.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad u256 b7 representation'); - let serialized = 111_felt252.format_as_byte_array(base: 7.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad felt252 b7 representation'); -} - -#[test] -fn test_to_string_base36() { - let base36: NonZero = 36_u8.try_into().unwrap(); - - let expected_string = "0"; - let serialized = 0_u8.format_as_byte_array(base36); - assert_eq(@serialized, @expected_string, 'Bad b36 representation of 0'); - - let expected_string = "a"; - let serialized = 10_u8.format_as_byte_array(base36); - assert_eq(@serialized, @expected_string, 'Bad b36 representation of 10'); - - let expected_string = "3z"; - let serialized = 143_u8.format_as_byte_array(base36); - assert_eq(@serialized, @expected_string, 'Bad b36 representation of 143'); - - let expected_string = "73"; - let serialized = 255_u8.format_as_byte_array(base36); - assert_eq(@serialized, @expected_string, 'Bad b36 representation of 255'); - - // Other uint types: - let expected_string = "3z"; - let serialized = 143_u16.format_as_byte_array(base: 36_u16.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad u16 b36 representation'); - let serialized = 143_u32.format_as_byte_array(base: 36_u32.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad u32 b36 representation'); - let serialized = 143_u64.format_as_byte_array(base: 36_u64.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad u64 b36 representation'); - let serialized = 143_u128.format_as_byte_array(base: 36_u128.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad u128 b36 representation'); - let serialized = 143_u256.format_as_byte_array(base: 36_u256.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad u256 b36 representation'); - let serialized = 143_felt252.format_as_byte_array(base: 36.try_into().unwrap()); - assert_eq(@serialized, @expected_string, 'Bad felt252 b36 representation'); -} - -#[test] -fn test_append() { - let expected = "prefix_6f"; - let mut byte_array = "prefix_"; - 111_u8.append_formatted_to_byte_array(ref byte_array, base: 16_u8.try_into().unwrap()); - assert_eq(@byte_array, @expected, 'Bad append u8'); - - let mut byte_array = "prefix_"; - 111_u16.append_formatted_to_byte_array(ref byte_array, base: 16_u16.try_into().unwrap()); - assert_eq(@byte_array, @expected, 'Bad append u16'); - - let mut byte_array = "prefix_"; - 111_u32.append_formatted_to_byte_array(ref byte_array, base: 16_u32.try_into().unwrap()); - assert_eq(@byte_array, @expected, 'Bad append u32'); - - let mut byte_array = "prefix_"; - 111_u64.append_formatted_to_byte_array(ref byte_array, base: 16_u64.try_into().unwrap()); - assert_eq(@byte_array, @expected, 'Bad append u64'); - - let mut byte_array = "prefix_"; - 111_u128.append_formatted_to_byte_array(ref byte_array, base: 16_u128.try_into().unwrap()); - assert_eq(@byte_array, @expected, 'Bad append u128'); - - let mut byte_array = "prefix_"; - 111_u256.append_formatted_to_byte_array(ref byte_array, base: 16_u256.try_into().unwrap()); - assert_eq(@byte_array, @expected, 'Bad append u256'); - - let mut byte_array = "prefix_"; - 111.append_formatted_to_byte_array(ref byte_array, base: 16.try_into().unwrap()); - assert_eq(@byte_array, @expected, 'Bad append felt252'); -} diff --git a/corelib/src/test/while_test.cairo b/corelib/src/test/while_test.cairo deleted file mode 100644 index 8283f4895..000000000 --- a/corelib/src/test/while_test.cairo +++ /dev/null @@ -1,27 +0,0 @@ -use core::test::test_utils::{assert_eq, assert_ne}; - -fn array_sum(mut arr: Array) -> felt252 { - let mut sum = 0; - while let Option::Some(x) = arr.pop_front() { - sum += x; - }; - sum -} - -#[test] -fn test_while_let() { - assert_eq!(array_sum(array![1, 2, 3, 4]), 10); - assert_eq!(array_sum(array![]), 0); -} - -#[test] -fn test_outer_loop_break() { - let mut i = 0; - while let true = i != 10 { - while true { - break; - }; - i += 1; - }; - assert_eq!(i, 10); -} diff --git a/corelib/src/testing.cairo b/corelib/src/testing.cairo deleted file mode 100644 index f7dc0ffcf..000000000 --- a/corelib/src/testing.cairo +++ /dev/null @@ -1 +0,0 @@ -pub extern fn get_available_gas() -> u128 implicits(GasBuiltin) nopanic; diff --git a/corelib/src/to_byte_array.cairo b/corelib/src/to_byte_array.cairo deleted file mode 100644 index 1ee7899a1..000000000 --- a/corelib/src/to_byte_array.cairo +++ /dev/null @@ -1,129 +0,0 @@ -use core::byte_array::ByteArrayTrait; -use core::traits::{Into, TryInto}; -use core::option::OptionTrait; -use core::zeroable::Zeroable; - -/// Formats a type that behaves like uint to its Ascii representation and appends the formatted -/// result into the given ByteArray. -pub trait AppendFormattedToByteArray { - fn append_formatted_to_byte_array(self: @T, ref byte_array: ByteArray, base: NonZero); -} - -/// Formats the given input of a type that behaves like uint to its Ascii representation in a -/// ByteArray. -pub trait FormatAsByteArray { - fn format_as_byte_array(self: @T, base: NonZero) -> ByteArray; -} - -impl FormatAsByteArrayImpl> of FormatAsByteArray { - fn format_as_byte_array(self: @T, base: NonZero) -> ByteArray { - let mut byte_array = ""; - self.append_formatted_to_byte_array(ref byte_array, :base); - byte_array - } -} - -// === Impls of AppendFormattedToByteArray === - -impl U8AppendFormattedToByteArray of AppendFormattedToByteArray { - fn append_formatted_to_byte_array(self: @u8, ref byte_array: ByteArray, base: NonZero) { - append_formatted_to_byte_array(self, ref byte_array, base); - } -} -impl U16AppendFormattedToByteArray of AppendFormattedToByteArray { - fn append_formatted_to_byte_array(self: @u16, ref byte_array: ByteArray, base: NonZero) { - append_formatted_to_byte_array(self, ref byte_array, base); - } -} -impl U32AppendFormattedToByteArray of AppendFormattedToByteArray { - fn append_formatted_to_byte_array(self: @u32, ref byte_array: ByteArray, base: NonZero) { - append_formatted_to_byte_array(self, ref byte_array, base); - } -} -impl U64AppendFormattedToByteArray of AppendFormattedToByteArray { - fn append_formatted_to_byte_array(self: @u64, ref byte_array: ByteArray, base: NonZero) { - append_formatted_to_byte_array(self, ref byte_array, base); - } -} -impl U128AppendFormattedToByteArray of AppendFormattedToByteArray { - fn append_formatted_to_byte_array(self: @u128, ref byte_array: ByteArray, base: NonZero) { - append_formatted_to_byte_array(self, ref byte_array, base); - } -} -impl U256AppendFormattedToByteArray of AppendFormattedToByteArray { - fn append_formatted_to_byte_array(self: @u256, ref byte_array: ByteArray, base: NonZero) { - append_formatted_to_byte_array(self, ref byte_array, base); - } -} -impl Felt252AppendFormattedToByteArray of AppendFormattedToByteArray { - fn append_formatted_to_byte_array( - self: @felt252, ref byte_array: ByteArray, base: NonZero - ) { - let self_as_u256: u256 = (*self).into(); - let base: felt252 = base.into(); - let base: u256 = base.into(); - let base: NonZero = base.try_into().unwrap(); - self_as_u256.append_formatted_to_byte_array(ref byte_array, base); - } -} - -// === helper functions === - -// TODO(yuval): once const generic parameters are supported, move base_nz to be a generic -// parameter. Same for the other bases. -// TODO(yuval): support signed integers. -/// Formats a type that behaves like uint to its Ascii representation and appends the formatted -/// result into the given ByteArray. -/// `base` must be in the range [2, 36]. Otherwise, this function panics. -fn append_formatted_to_byte_array< - T, +Drop, +Copy, +DivRem, +TryInto, +Zeroable, ->( - mut value: @T, ref byte_array: ByteArray, base_nz: NonZero, -) { - let base: T = base_nz.into(); - let base: u8 = base.try_into().unwrap(); - assert(base > 1, 'base must be > 1'); - assert(base <= 36, 'base must be <= 36'); - - let mut reversed_digits = array![]; - - if base <= 10 { - loop { - let (new_value, digit) = DivRem::div_rem(*value, base_nz); - value = @new_value; - let digit_as_u8: u8 = digit.try_into().unwrap(); - reversed_digits.append(digit_as_u8 + '0'); - if (*value).is_zero() { - break; - }; - } - } else { - loop { - let (new_value, digit) = DivRem::div_rem(*value, base_nz); - value = @new_value; - let digit_as_u8: u8 = digit.try_into().unwrap(); - reversed_digits.append(get_big_base_digit_representation(:digit_as_u8)); - if (*value).is_zero() { - break; - }; - }; - } - - let mut span = reversed_digits.span(); - loop { - match span.pop_back() { - Option::Some(byte) => { byte_array.append_byte(*byte); }, - Option::None => { break; }, - }; - }; -} - -/// Converts a digit (0-9, A-Z) to its Ascii representation in a base > 10. -#[inline] -fn get_big_base_digit_representation(digit_as_u8: u8) -> u8 { - if digit_as_u8 < 10 { - digit_as_u8 + '0' - } else { - digit_as_u8 - 10 + 'a' - } -} diff --git a/corelib/src/traits.cairo b/corelib/src/traits.cairo deleted file mode 100644 index 0ec69bd2a..000000000 --- a/corelib/src/traits.cairo +++ /dev/null @@ -1,312 +0,0 @@ -use core::panics::Panic; - -pub trait Copy; -pub trait Drop; - -impl SnapshotCopy of Copy<@T>; -impl SnapshotDrop of Drop<@T>; - -// TODO(spapini): When associated types are supported, support the general trait Add. -pub trait Add { - fn add(lhs: T, rhs: T) -> T; -} -pub trait AddEq { - fn add_eq(ref self: T, other: T); -} - -// TODO(spapini): When associated types are supported, support the general trait Sub. -pub trait Sub { - fn sub(lhs: T, rhs: T) -> T; -} -pub trait SubEq { - fn sub_eq(ref self: T, other: T); -} - -// TODO(spapini): When associated types are supported, support the general trait Mul. -pub trait Mul { - fn mul(lhs: T, rhs: T) -> T; -} -pub trait MulEq { - fn mul_eq(ref self: T, other: T); -} - -// TODO(spapini): When associated types are supported, support the general trait Div. -pub trait Div { - fn div(lhs: T, rhs: T) -> T; -} -pub trait DivEq { - fn div_eq(ref self: T, other: T); -} - -// TODO(spapini): When associated types are supported, support the general trait Rem. -pub trait Rem { - fn rem(lhs: T, rhs: T) -> T; -} -pub trait RemEq { - fn rem_eq(ref self: T, other: T); -} - -// TODO(spapini): When associated types are supported, support the general trait DivRem. -/// Division with remainder. -pub trait DivRem { - fn div_rem(lhs: T, rhs: NonZero) -> (T, T); -} - -pub trait PartialEq { - fn eq(lhs: @T, rhs: @T) -> bool; - fn ne(lhs: @T, rhs: @T) -> bool; -} -impl PartialEqSnap> of PartialEq<@T> { - fn eq(lhs: @@T, rhs: @@T) -> bool { - PartialEq::::eq(*lhs, *rhs) - } - fn ne(lhs: @@T, rhs: @@T) -> bool { - PartialEq::::ne(*lhs, *rhs) - } -} - -// TODO(spapini): When associated types are supported, support the general trait BitAnd. -pub trait BitAnd { - fn bitand(lhs: T, rhs: T) -> T; -} - -// TODO(spapini): When associated types are supported, support the general trait BitOr. -pub trait BitOr { - fn bitor(lhs: T, rhs: T) -> T; -} - -// TODO(spapini): When associated types are supported, support the general trait BitXor. -pub trait BitXor { - fn bitxor(lhs: T, rhs: T) -> T; -} - -pub trait BitNot { - fn bitnot(a: T) -> T; -} - -pub trait PartialOrd { - fn le(lhs: T, rhs: T) -> bool; - fn ge(lhs: T, rhs: T) -> bool; - fn lt(lhs: T, rhs: T) -> bool; - fn gt(lhs: T, rhs: T) -> bool; -} - -/// Trait for conversion between types. -pub trait Into { - #[must_use] - fn into(self: T) -> S; -} - -impl TIntoT of Into { - fn into(self: T) -> T { - self - } -} - -/// Trait for fallible conversion between types. -pub trait TryInto { - fn try_into(self: T) -> Option; -} - -impl TryIntoFromInto> of TryInto { - fn try_into(self: From) -> Option { - Option::Some(self.into()) - } -} - -pub trait Neg { - fn neg(a: T) -> T; -} - -pub trait Not { - fn not(a: T) -> T; -} - -/// The following two traits are for implementing the [] operator. Only one should be implemented -/// for each type. Both are not consuming of self, the first gets a snapshot of the object and -/// the second gets ref. -pub trait IndexView { - fn index(self: @C, index: I) -> V; -} - -pub trait Index { - fn index(ref self: C, index: I) -> V; -} - -pub trait Destruct { - fn destruct(self: T) nopanic; -} -// TODO(spapini): Remove this, it can lead to multiple impls and unwanted Destruct implementation. -impl DestructFromDrop> of Destruct { - #[inline(always)] - fn destruct(self: T) nopanic {} -} - -pub trait PanicDestruct { - fn panic_destruct(self: T, ref panic: Panic) nopanic; -} -impl PanicDestructForDestruct> of PanicDestruct { - #[inline(always)] - fn panic_destruct(self: T, ref panic: Panic) nopanic { - Destruct::destruct(self); - } -} - -pub trait Default { - #[must_use] - fn default() -> T; -} - -impl SnapshotDefault, +Drop> of Default<@T> { - #[inline(always)] - fn default() -> @T { - @Default::default() - } -} - -/// Trait for types allowed as values in a Felt252Dict. -pub trait Felt252DictValue { - /// Returns the default value for this type as a value in a Felt252Dict. - /// Should be logically equivalent to 0. - #[must_use] - fn zero_default() -> T nopanic; -} - -// Tuple Copy impls. -pub(crate) impl TupleSize0Copy of Copy<()>; - -impl TupleSize1Copy> of Copy<(E0,)>; - -impl TupleSize2Copy, +Copy> of Copy<(E0, E1)>; - -impl TupleSize3Copy, +Copy, +Copy> of Copy<(E0, E1, E2)>; - -impl TupleSize4Copy< - E0, E1, E2, E3, +Copy, +Copy, +Copy, +Copy -> of Copy<(E0, E1, E2, E3)>; - -// Tuple Drop impls. -pub(crate) impl TupleSize0Drop of Drop<()>; - -impl TupleSize1Drop> of Drop<(E0,)>; - -impl TupleSize2Drop, +Drop> of Drop<(E0, E1)>; - -impl TupleSize3Drop, +Drop, +Drop> of Drop<(E0, E1, E2)>; - -impl TupleSize4Drop< - E0, E1, E2, E3, +Drop, +Drop, +Drop, +Drop -> of Drop<(E0, E1, E2, E3)>; - -// Tuple PartialEq impls. -impl TupleSize0PartialEq of PartialEq<()> { - #[inline(always)] - fn eq(lhs: @(), rhs: @()) -> bool { - true - } - #[inline(always)] - fn ne(lhs: @(), rhs: @()) -> bool { - false - } -} - -impl TupleSize1PartialEq> of PartialEq<(E0,)> { - #[inline(always)] - fn eq(lhs: @(E0,), rhs: @(E0,)) -> bool { - let (lhs,) = lhs; - let (rhs,) = rhs; - lhs == rhs - } - #[inline(always)] - fn ne(lhs: @(E0,), rhs: @(E0,)) -> bool { - !(rhs == lhs) - } -} - -impl TupleSize2PartialEq, +PartialEq> of PartialEq<(E0, E1)> { - #[inline(always)] - fn eq(lhs: @(E0, E1), rhs: @(E0, E1)) -> bool { - let (lhs0, lhs1) = lhs; - let (rhs0, rhs1) = rhs; - lhs0 == rhs0 && lhs1 == rhs1 - } - #[inline(always)] - fn ne(lhs: @(E0, E1), rhs: @(E0, E1)) -> bool { - !(rhs == lhs) - } -} - -impl TupleSize3PartialEq< - E0, E1, E2, +PartialEq, +PartialEq, +PartialEq -> of PartialEq<(E0, E1, E2)> { - #[inline(always)] - fn eq(lhs: @(E0, E1, E2), rhs: @(E0, E1, E2)) -> bool { - let (lhs0, lhs1, lhs2) = lhs; - let (rhs0, rhs1, rhs2) = rhs; - lhs0 == rhs0 && lhs1 == rhs1 && lhs2 == rhs2 - } - #[inline(always)] - fn ne(lhs: @(E0, E1, E2), rhs: @(E0, E1, E2)) -> bool { - !(rhs == lhs) - } -} - -impl TupleSize4PartialEq< - E0, E1, E2, E3, +PartialEq, +PartialEq, +PartialEq, +PartialEq -> of PartialEq<(E0, E1, E2, E3)> { - #[inline(always)] - fn eq(lhs: @(E0, E1, E2, E3), rhs: @(E0, E1, E2, E3)) -> bool { - let (lhs0, lhs1, lhs2, lhs3) = lhs; - let (rhs0, rhs1, rhs2, rhs3) = rhs; - lhs0 == rhs0 && lhs1 == rhs1 && lhs2 == rhs2 && lhs3 == rhs3 - } - #[inline(always)] - fn ne(lhs: @(E0, E1, E2, E3), rhs: @(E0, E1, E2, E3)) -> bool { - !(rhs == lhs) - } -} - -// Tuple Default impls. -impl TupleSize0Default of Default<()> { - fn default() -> () { - () - } -} - -impl TupleSize1Default> of Default<(E0,)> { - fn default() -> (E0,) { - (Default::default(),) - } -} - -impl TupleSize2Default, +Drop, +Default> of Default<(E0, E1)> { - fn default() -> (E0, E1) { - (Default::default(), Default::default()) - } -} - -impl TupleSize3Default< - E0, E1, E2, +Default, +Drop, +Default, +Drop, +Default -> of Default<(E0, E1, E2)> { - fn default() -> (E0, E1, E2) { - (Default::default(), Default::default(), Default::default()) - } -} - -impl TupleSize4Default< - E0, - E1, - E2, - E3, - +Default, - +Drop, - +Default, - +Drop, - +Default, - +Drop, - +Default -> of Default<(E0, E1, E2, E3)> { - fn default() -> (E0, E1, E2, E3) { - (Default::default(), Default::default(), Default::default(), Default::default()) - } -} diff --git a/corelib/src/zeroable.cairo b/corelib/src/zeroable.cairo deleted file mode 100644 index b22503db4..000000000 --- a/corelib/src/zeroable.cairo +++ /dev/null @@ -1,84 +0,0 @@ -// === Zeroable === - -pub(crate) trait Zeroable { - /// Returns the additive identity element of Self, 0. - #[must_use] - fn zero() -> T; - /// Returns whether self is equal to 0, the additive identity element. - #[must_use] - fn is_zero(self: T) -> bool; - /// Returns whether self is not equal to 0, the additive identity element. - #[must_use] - fn is_non_zero(self: T) -> bool; -} - -pub(crate) mod zero_based { - pub(crate) impl ZeroableImpl< - T, impl ZeroImpl: core::num::traits::Zero, +Drop, +Copy - > of super::Zeroable { - fn zero() -> T { - ZeroImpl::zero() - } - #[inline(always)] - fn is_zero(self: T) -> bool { - ZeroImpl::is_zero(@self) - } - #[inline(always)] - fn is_non_zero(self: T) -> bool { - ZeroImpl::is_non_zero(@self) - } - } -} - -pub(crate) impl Felt252Zeroable = zero_based::ZeroableImpl; - -// === NonZero === - -#[derive(Copy, Drop)] -pub extern type NonZero; - -pub(crate) enum IsZeroResult { - Zero, - NonZero: NonZero, -} -extern fn unwrap_non_zero(a: NonZero) -> T nopanic; - -pub(crate) impl NonZeroIntoImpl of Into, T> { - fn into(self: NonZero) -> T nopanic { - unwrap_non_zero(self) - } -} - -impl IsZeroResultIntoBool> of Into, bool> { - fn into(self: IsZeroResult) -> bool { - match self { - IsZeroResult::Zero => true, - IsZeroResult::NonZero(_) => false, - } - } -} - -impl NonZeroPartialEq, +Copy, +Drop> of PartialEq> { - #[inline(always)] - fn eq(lhs: @NonZero, rhs: @NonZero) -> bool { - let lhs: T = (*lhs).into(); - let rhs: T = (*rhs).into(); - lhs == rhs - } - #[inline(always)] - fn ne(lhs: @NonZero, rhs: @NonZero) -> bool { - let lhs: T = (*lhs).into(); - let rhs: T = (*rhs).into(); - lhs != rhs - } -} - -impl NonZeroSerde, +Copy, +Drop, +TryInto>> of Serde> { - fn serialize(self: @NonZero, ref output: Array) { - let value: T = (*self).into(); - value.serialize(ref output); - } - fn deserialize(ref serialized: Span) -> Option> { - Serde::::deserialize(ref serialized)?.try_into() - } -} diff --git a/exercises/Scarb.lock b/exercises/Scarb.lock new file mode 100644 index 000000000..594a8c539 --- /dev/null +++ b/exercises/Scarb.lock @@ -0,0 +1,24 @@ +# Code generated by scarb DO NOT EDIT. +version = 1 + +[[package]] +name = "snforge_scarb_plugin" +version = "0.44.0" +source = "registry+https://scarbs.xyz/" +checksum = "sha256:ec8c7637b33392a53153c1e5b87a4617ddcb1981951b233ea043cad5136697e2" + +[[package]] +name = "snforge_std" +version = "0.44.0" +source = "registry+https://scarbs.xyz/" +checksum = "sha256:d4affedfb90715b1ac417b915c0a63377ae6dd69432040e5d933130d65114702" +dependencies = [ + "snforge_scarb_plugin", +] + +[[package]] +name = "starklings_cairo1" +version = "0.1.0" +dependencies = [ + "snforge_std", +] diff --git a/exercises/starknet/basics/starknet1.cairo b/exercises/starknet/basics/starknet1.cairo index a919afbac..86e9b9559 100644 --- a/exercises/starknet/basics/starknet1.cairo +++ b/exercises/starknet/basics/starknet1.cairo @@ -24,24 +24,19 @@ mod JoesContract { #[cfg(test)] mod test { use super::JoesContract; - use starknet::syscalls::deploy_syscall; use super::IJoesContractDispatcher; use super::IJoesContractDispatcherTrait; + use snforge_std::{declare, ContractClassTrait, DeclareResultTrait}; #[test] - #[available_gas(2000000000)] fn test_contract_view() { let dispatcher = deploy_contract(); assert('Joe' == dispatcher.get_owner(), 'Joe should be the owner.'); } fn deploy_contract() -> IJoesContractDispatcher { - let mut calldata = ArrayTrait::new(); - let (address0, _) = deploy_syscall( - JoesContract::TEST_CLASS_HASH.try_into().unwrap(), 0, calldata.span(), false - ) - .unwrap(); - let contract0 = IJoesContractDispatcher { contract_address: address0 }; - contract0 + let contract = declare("JoesContract").unwrap().contract_class(); + let (contract_address, _) = contract.deploy(@array![]).unwrap(); + IJoesContractDispatcher { contract_address } } } diff --git a/exercises/starknet/basics/starknet2.cairo b/exercises/starknet/basics/starknet2.cairo index efbdb874a..8ed443e48 100644 --- a/exercises/starknet/basics/starknet2.cairo +++ b/exercises/starknet/basics/starknet2.cairo @@ -37,21 +37,19 @@ trait IJillsContract { #[cfg(test)] mod test { - use starknet::syscalls::deploy_syscall; use super::IJillsContractDispatcher; use super::IJillsContractDispatcherTrait; - use super::JillsContract; + use snforge_std::{declare, ContractClassTrait, DeclareResultTrait}; + #[test] - #[available_gas(2000000000)] fn test_owner_setting() { let mut calldata = ArrayTrait::new(); calldata.append('Jill'); - let (address0, _) = deploy_syscall( - JillsContract::TEST_CLASS_HASH.try_into().unwrap(), 0, calldata.span(), false - ) - .unwrap(); - let dispatcher = IJillsContractDispatcher { contract_address: address0 }; + + let contract = declare("JillsContract").unwrap().contract_class(); + let (contract_address, _) = contract.deploy(@calldata).unwrap(); + let dispatcher = IJillsContractDispatcher { contract_address }; let owner = dispatcher.get_owner(); assert(owner == 'Jill'.try_into().unwrap(), 'Owner should be Jill'); } diff --git a/exercises/starknet/basics/starknet3.cairo b/exercises/starknet/basics/starknet3.cairo index 3ce6e1ef5..e12c6c3be 100644 --- a/exercises/starknet/basics/starknet3.cairo +++ b/exercises/starknet/basics/starknet3.cairo @@ -20,7 +20,7 @@ mod ProgressTracker { use starknet::ContractAddress; use starknet::get_caller_address; // Required to use get_caller_address function use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess, StoragePathEntry, Map}; - + #[storage] struct Storage { contract_owner: ContractAddress, @@ -54,13 +54,12 @@ mod ProgressTracker { #[cfg(test)] mod test { use starknet::ContractAddress; - use starknet::syscalls::deploy_syscall; use super::IProgressTrackerDispatcher; use super::IProgressTrackerDispatcherTrait; use super::ProgressTracker; + use snforge_std::{declare, ContractClassTrait, DeclareResultTrait, start_cheat_caller_address, stop_cheat_caller_address}; #[test] - #[available_gas(2000000000)] fn test_owner() { let owner: ContractAddress = 'Sensei'.try_into().unwrap(); let dispatcher = deploy_contract(); @@ -68,13 +67,12 @@ mod test { } #[test] - #[available_gas(2000000000)] fn test_set_progress() { let owner = util_felt_addr('Sensei'); let dispatcher = deploy_contract(); // Call contract as owner - starknet::testing::set_contract_address(owner); + start_cheat_caller_address(dispatcher.contract_address, owner); // Set progress dispatcher.set_progress('Joe'.try_into().unwrap(), 20); @@ -82,20 +80,23 @@ mod test { let joe_score = dispatcher.get_progress('Joe'.try_into().unwrap()); assert(joe_score == 20, 'Joe\'s progress should be 20'); + + stop_cheat_caller_address(dispatcher.contract_address); } #[test] #[should_panic] - #[available_gas(2000000000)] fn test_set_progress_fail() { let dispatcher = deploy_contract(); let jon_doe = util_felt_addr('JonDoe'); // Caller not owner - starknet::testing::set_contract_address(jon_doe); + start_cheat_caller_address(dispatcher.contract_address, jon_doe); // Try to set progress, should panic to pass test! dispatcher.set_progress('Joe'.try_into().unwrap(), 20); + + stop_cheat_caller_address(dispatcher.contract_address); } fn util_felt_addr(addr_felt: felt252) -> ContractAddress { @@ -106,11 +107,9 @@ mod test { let owner: felt252 = 'Sensei'; let mut calldata = ArrayTrait::new(); calldata.append(owner); - let (address0, _) = deploy_syscall( - ProgressTracker::TEST_CLASS_HASH.try_into().unwrap(), 0, calldata.span(), false - ) - .unwrap(); - let contract0 = IProgressTrackerDispatcher { contract_address: address0 }; - contract0 + + let contract = declare("ProgressTracker").unwrap().contract_class(); + let (contract_address, _) = contract.deploy(@calldata).unwrap(); + IProgressTrackerDispatcher { contract_address } } } diff --git a/exercises/starknet/basics/starknet4.cairo b/exercises/starknet/basics/starknet4.cairo index cb7d62566..dcb122610 100644 --- a/exercises/starknet/basics/starknet4.cairo +++ b/exercises/starknet/basics/starknet4.cairo @@ -63,13 +63,12 @@ mod LizInventory { #[cfg(test)] mod test { use starknet::ContractAddress; - use starknet::syscalls::deploy_syscall; use super::LizInventory; use super::ILizInventoryDispatcher; use super::ILizInventoryDispatcherTrait; + use snforge_std::{declare, ContractClassTrait, DeclareResultTrait, start_cheat_caller_address, stop_cheat_caller_address}; #[test] - #[available_gas(2000000000)] fn test_owner() { let owner: ContractAddress = 'Elizabeth'.try_into().unwrap(); let dispatcher = deploy_contract(); @@ -80,13 +79,12 @@ mod test { } #[test] - #[available_gas(2000000000)] fn test_stock() { let dispatcher = deploy_contract(); let owner = util_felt_addr('Elizabeth'); // Call contract as owner - starknet::testing::set_contract_address(owner); + start_cheat_caller_address(dispatcher.contract_address, owner); // Add stock dispatcher.add_stock('Nano', 10); @@ -96,32 +94,35 @@ mod test { dispatcher.add_stock('Nano', 15); let stock = dispatcher.get_stock('Nano'); assert(stock == 25, 'stock should be 25'); + + stop_cheat_caller_address(dispatcher.contract_address); } #[test] - #[available_gas(2000000000)] fn test_stock_purchase() { let owner = util_felt_addr('Elizabeth'); let dispatcher = deploy_contract(); // Call contract as owner - starknet::testing::set_contract_address(owner); + start_cheat_caller_address(dispatcher.contract_address, owner); // Add stock dispatcher.add_stock('Nano', 10); let stock = dispatcher.get_stock('Nano'); assert(stock == 10, 'stock should be 10'); - // Call contract as owner - starknet::testing::set_caller_address(0.try_into().unwrap()); + // Call contract as different address + stop_cheat_caller_address(dispatcher.contract_address); + start_cheat_caller_address(dispatcher.contract_address, 0.try_into().unwrap()); dispatcher.purchase('Nano', 2); let stock = dispatcher.get_stock('Nano'); assert(stock == 8, 'stock should be 8'); + + stop_cheat_caller_address(dispatcher.contract_address); } #[test] #[should_panic] - #[available_gas(2000000000)] fn test_set_stock_fail() { let dispatcher = deploy_contract(); // Try to add stock, should panic to pass test! @@ -130,10 +131,9 @@ mod test { #[test] #[should_panic] - #[available_gas(2000000000)] fn test_purchase_out_of_stock() { let dispatcher = deploy_contract(); - // Purchse out of stock + // Purchase out of stock dispatcher.purchase('Nano', 2); } @@ -145,11 +145,9 @@ mod test { let owner: felt252 = 'Elizabeth'; let mut calldata = ArrayTrait::new(); calldata.append(owner); - let (address0, _) = deploy_syscall( - LizInventory::TEST_CLASS_HASH.try_into().unwrap(), 0, calldata.span(), false - ) - .unwrap(); - let contract0 = ILizInventoryDispatcher { contract_address: address0 }; - contract0 + + let contract = declare("LizInventory").unwrap().contract_class(); + let (contract_address, _) = contract.deploy(@calldata).unwrap(); + ILizInventoryDispatcher { contract_address } } } diff --git a/exercises/starknet/components/starknet6.cairo b/exercises/starknet/components/starknet6.cairo index de9734f38..d7dc3e20b 100644 --- a/exercises/starknet/components/starknet6.cairo +++ b/exercises/starknet/components/starknet6.cairo @@ -60,35 +60,31 @@ mod OwnableCounter { #[cfg(test)] mod tests { - use super::OwnableCounter; - use super::{IOwnableDispatcher, IOwnable, IOwnableDispatcherTrait}; - use starknet::syscalls::deploy_syscall; + use snforge_std::{declare, ContractClassTrait, DeclareResultTrait}; + use starknet::{contract_address_const, ContractAddress}; + use super::IOwnableDispatcher; + + fn deploy_ownable_counter() -> IOwnableDispatcher { + let contract = declare("OwnableCounter").unwrap().contract_class(); + let (contract_address, _) = contract.deploy(@array![]).unwrap(); + IOwnableDispatcher { contract_address } + } #[test] - #[available_gas(200_000_000)] fn test_contract_read() { - let dispatcher = deploy_contract(); + let dispatcher = deploy_ownable_counter(); let address_0 = 0; dispatcher.set_owner(address_0.try_into().unwrap()); assert(address_0.try_into().unwrap() == dispatcher.owner(), 'Some fuck up happened'); } + #[test] - #[available_gas(200_000_000)] #[should_panic] fn test_contract_read_fail() { - let dispatcher = deploy_contract(); + let dispatcher = deploy_ownable_counter(); let address_0 = 0; let address_1 = 1; dispatcher.set_owner(address_0.try_into().unwrap()); assert(address_1.try_into().unwrap() == dispatcher.owner(), 'Some fuck up happened'); } - fn deploy_contract() -> IOwnableDispatcher { - let mut calldata = ArrayTrait::new(); - let (address0, _) = deploy_syscall( - OwnableCounter::TEST_CLASS_HASH.try_into().unwrap(), 0, calldata.span(), false - ) - .unwrap(); - let contract0 = IOwnableDispatcher { contract_address: address0 }; - contract0 - } } diff --git a/exercises/starknet/interoperability/starknet5.cairo b/exercises/starknet/interoperability/starknet5.cairo index 3904c6523..c9e3d5ec9 100644 --- a/exercises/starknet/interoperability/starknet5.cairo +++ b/exercises/starknet/interoperability/starknet5.cairo @@ -74,35 +74,31 @@ mod ContractB { #[cfg(test)] mod test { - use starknet::syscalls::deploy_syscall; - use super::ContractA; - use super::IContractADispatcher; - use super::IContractADispatcherTrait; - use super::ContractB; - use super::IContractBDispatcher; - use super::IContractBDispatcherTrait; + use snforge_std::{declare, ContractClassTrait, DeclareResultTrait}; + use starknet::ContractAddress; + use super::{IContractBDispatcher, IContractADispatcher, IContractADispatcherTrait, IContractBDispatcherTrait}; + + fn deploy_contract_b() -> IContractBDispatcher { + let contract = declare("ContractB").unwrap().contract_class(); + let (contract_address, _) = contract.deploy(@array![]).unwrap(); + IContractBDispatcher { contract_address } + } + + fn deploy_contract_a(contract_b_address: ContractAddress) -> IContractADispatcher { + let contract = declare("ContractA").unwrap().contract_class(); + let constructor_calldata = array![contract_b_address.into()]; + let (contract_address, _) = contract.deploy(@constructor_calldata).unwrap(); + IContractADispatcher { contract_address } + } #[test] - #[available_gas(30000000)] fn test_interoperability() { // Deploy ContractB - let (address_b, _) = deploy_syscall( - ContractB::TEST_CLASS_HASH.try_into().unwrap(), 0, ArrayTrait::new().span(), false - ) - .unwrap(); + let contract_b = deploy_contract_b(); // Deploy ContractA - let mut calldata = ArrayTrait::new(); - calldata.append(address_b.into()); - let (address_a, _) = deploy_syscall( - ContractA::TEST_CLASS_HASH.try_into().unwrap(), 0, calldata.span(), false - ) - .unwrap(); - - // contract_a is of type IContractADispatcher. Its methods are defined in IContractADispatcherTrait. - let contract_a = IContractADispatcher { contract_address: address_a }; - let contract_b = IContractBDispatcher { contract_address: address_b }; + let contract_a = deploy_contract_a(contract_b.contract_address); //TODO interact with contract_b to make the test pass. diff --git a/runner-crate/.snfoundry_cache/.prev_tests_failed b/runner-crate/.snfoundry_cache/.prev_tests_failed new file mode 100644 index 000000000..e69de29bb diff --git a/runner-crate/Scarb.lock b/runner-crate/Scarb.lock index 34fdb7e85..f603c1903 100644 --- a/runner-crate/Scarb.lock +++ b/runner-crate/Scarb.lock @@ -2,5 +2,23 @@ version = 1 [[package]] -name = "exercise_crate" +name = "runner_crate" version = "0.1.0" +dependencies = [ + "snforge_std", +] + +[[package]] +name = "snforge_scarb_plugin" +version = "0.44.0" +source = "registry+https://scarbs.xyz/" +checksum = "sha256:ec8c7637b33392a53153c1e5b87a4617ddcb1981951b233ea043cad5136697e2" + +[[package]] +name = "snforge_std" +version = "0.44.0" +source = "registry+https://scarbs.xyz/" +checksum = "sha256:d4affedfb90715b1ac417b915c0a63377ae6dd69432040e5d933130d65114702" +dependencies = [ + "snforge_scarb_plugin", +] diff --git a/runner-crate/Scarb.toml b/runner-crate/Scarb.toml index a1a438437..4b848bfd9 100644 --- a/runner-crate/Scarb.toml +++ b/runner-crate/Scarb.toml @@ -1,11 +1,21 @@ [package] -name = "exercise_crate" +name = "runner_crate" version = "0.1.0" +edition = "2024_07" -# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html [dependencies] -starknet = "2.8.2" +starknet = "2.11.4" [dev-dependencies] -cairo_test = "2.8.2" +snforge_std = "0.44.0" +assert_macros = "2.11.4" + +[[target.starknet-contract]] +sierra = true + +[scripts] +test = "snforge test" + +[tool.scarb] +allow-prebuilt-plugins = ["snforge_std"] diff --git a/rust-toolchain b/rust-toolchain new file mode 100644 index 000000000..06810703e --- /dev/null +++ b/rust-toolchain @@ -0,0 +1,4 @@ +[toolchain] +channel = "1.86.0" +components = ["rustfmt", "clippy"] +profile = "minimal" diff --git a/solutions/starknet/basics/starknet1.cairo b/solutions/starknet/basics/starknet1.cairo new file mode 100644 index 000000000..b58a640bf --- /dev/null +++ b/solutions/starknet/basics/starknet1.cairo @@ -0,0 +1,41 @@ +// Starkling, Joe, is writing a really simple contract. +// The contract shows that he is the owner of the contract. +// However, his contract is not working. What's he missing? + +#[starknet::interface] +trait IJoesContract { + fn get_owner(self: @TContractState) -> felt252; +} + +#[starknet::contract] +mod JoesContract { + #[storage] + struct Storage {} + + #[abi(embed_v0)] + impl IJoesContractImpl of super::IJoesContract { + fn get_owner(self: @ContractState) -> felt252 { + 'Joe' + } + } +} + +#[cfg(test)] +mod test { + use super::JoesContract; + use super::IJoesContractDispatcher; + use super::IJoesContractDispatcherTrait; + use snforge_std::{declare, ContractClassTrait, DeclareResultTrait}; + + #[test] + fn test_contract_view() { + let dispatcher = deploy_contract(); + assert('Joe' == dispatcher.get_owner(), 'Joe should be the owner.'); + } + + fn deploy_contract() -> IJoesContractDispatcher { + let contract = declare("JoesContract").unwrap().contract_class(); + let (contract_address, _) = contract.deploy(@array![]).unwrap(); + IJoesContractDispatcher { contract_address } + } +} diff --git a/solutions/starknet/basics/starknet2.cairo b/solutions/starknet/basics/starknet2.cairo new file mode 100644 index 000000000..23a1ea339 --- /dev/null +++ b/solutions/starknet/basics/starknet2.cairo @@ -0,0 +1,58 @@ +// Joe's contract in the last exercise showed that Joe is the owner of the contract. +// He thanks you for helping him out! +// Jill says that contract should allow setting the owner when contract is deployed. +// Help Jill rewrite the contract with a Storage and a constructor. +// There is a `ContractAddress` type which should be used for Wallet addresses. + +use starknet::ContractAddress; + +#[starknet::contract] +mod JillsContract { + // This is required to use ContractAddress type + use starknet::ContractAddress; + use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; + + #[storage] + struct Storage { + contract_owner: ContractAddress, + } + + #[constructor] + fn constructor( + ref self: ContractState, owner: ContractAddress + ) { + self.contract_owner.write(owner); + } + + #[abi(embed_v0)] + impl IJillsContractImpl of super::IJillsContract { + fn get_owner(self: @ContractState) -> ContractAddress { + self.contract_owner.read() + } + } +} + +#[starknet::interface] +trait IJillsContract { + fn get_owner(self: @TContractState) -> ContractAddress; +} + +#[cfg(test)] +mod test { + use super::IJillsContractDispatcher; + use super::IJillsContractDispatcherTrait; + use super::JillsContract; + use snforge_std::{declare, ContractClassTrait, DeclareResultTrait}; + + #[test] + fn test_owner_setting() { + let mut calldata = ArrayTrait::new(); + calldata.append('Jill'); + + let contract = declare("JillsContract").unwrap().contract_class(); + let (contract_address, _) = contract.deploy(@calldata).unwrap(); + let dispatcher = IJillsContractDispatcher { contract_address }; + let owner = dispatcher.get_owner(); + assert(owner == 'Jill'.try_into().unwrap(), 'Owner should be Jill'); + } +} diff --git a/solutions/starknet/basics/starknet3.cairo b/solutions/starknet/basics/starknet3.cairo new file mode 100644 index 000000000..af21fe2ad --- /dev/null +++ b/solutions/starknet/basics/starknet3.cairo @@ -0,0 +1,120 @@ +// Joe liked Jill's work very much. He really likes how useful storage can be. +// Now they decided to write a contract to track the number of exercises they +// complete successfully. Jill says they can use the owner code and allow +// only the owner to update the contract, they agree. +// Can you help them write this contract? + +use starknet::ContractAddress; + +#[starknet::interface] +trait IProgressTracker { + fn set_progress(ref self: TContractState, user: ContractAddress, new_progress: u16); + fn get_progress(self: @TContractState, user: ContractAddress) -> u16; + fn get_contract_owner(self: @TContractState) -> ContractAddress; +} + +#[starknet::contract] +mod ProgressTracker { + use starknet::ContractAddress; + use starknet::get_caller_address; // Required to use get_caller_address function + use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess, StoragePathEntry, Map, StorageMapReadAccess, StorageMapWriteAccess}; + + #[storage] + struct Storage { + contract_owner: ContractAddress, + progress: Map + } + + #[constructor] + fn constructor(ref self: ContractState, owner: ContractAddress) { + self.contract_owner.write(owner); + } + + + #[abi(embed_v0)] + impl ProgressTrackerImpl of super::IProgressTracker { + fn set_progress( + ref self: ContractState, user: ContractAddress, new_progress: u16 + ) { + // Assert owner is calling + let caller = get_caller_address(); + let owner = self.contract_owner.read(); + assert(caller == owner, 'Only owner can set progress'); + + // Set new_progress for user + self.progress.write(user, new_progress); + } + + fn get_progress(self: @ContractState, user: ContractAddress) -> u16 { + // Get user progress + self.progress.read(user) + } + + fn get_contract_owner(self: @ContractState) -> ContractAddress { + self.contract_owner.read() + } + } +} + +#[cfg(test)] +mod test { + use starknet::ContractAddress; + use super::IProgressTrackerDispatcher; + use super::IProgressTrackerDispatcherTrait; + use super::ProgressTracker; + use snforge_std::{declare, ContractClassTrait, DeclareResultTrait, start_cheat_caller_address, stop_cheat_caller_address}; + + #[test] + fn test_owner() { + let owner: ContractAddress = 'Sensei'.try_into().unwrap(); + let dispatcher = deploy_contract(); + assert(owner == dispatcher.get_contract_owner(), 'Mr. Sensei should be the owner'); + } + + #[test] + fn test_set_progress() { + let owner = util_felt_addr('Sensei'); + let dispatcher = deploy_contract(); + + // Call contract as owner + start_cheat_caller_address(dispatcher.contract_address, owner); + + // Set progress + dispatcher.set_progress('Joe'.try_into().unwrap(), 20); + dispatcher.set_progress('Jill'.try_into().unwrap(), 25); + + let joe_score = dispatcher.get_progress('Joe'.try_into().unwrap()); + assert(joe_score == 20, 'Joe\'s progress should be 20'); + + stop_cheat_caller_address(dispatcher.contract_address); + } + + #[test] + #[should_panic] + fn test_set_progress_fail() { + let dispatcher = deploy_contract(); + + let jon_doe = util_felt_addr('JonDoe'); + // Caller not owner + start_cheat_caller_address(dispatcher.contract_address, jon_doe); + + // Try to set progress, should panic to pass test! + dispatcher.set_progress('Joe'.try_into().unwrap(), 20); + + stop_cheat_caller_address(dispatcher.contract_address); + } + + fn util_felt_addr(addr_felt: felt252) -> ContractAddress { + addr_felt.try_into().unwrap() + } + + fn deploy_contract() -> IProgressTrackerDispatcher { + let owner: felt252 = 'Sensei'; + let mut calldata = ArrayTrait::new(); + calldata.append(owner); + + let contract = declare("ProgressTracker").unwrap().contract_class(); + let (contract_address, _) = contract.deploy(@calldata).unwrap(); + IProgressTrackerDispatcher { contract_address } + } +} diff --git a/solutions/starknet/basics/starknet4.cairo b/solutions/starknet/basics/starknet4.cairo new file mode 100644 index 000000000..9e611b83d --- /dev/null +++ b/solutions/starknet/basics/starknet4.cairo @@ -0,0 +1,158 @@ +// Liz, a friend of Jill, wants to manage inventory for her store on-chain. +// This is a bit challenging for Joe and Jill, Liz prepared an outline +// for how contract should work, can you help Jill and Joe write it? + +use starknet::ContractAddress; + +#[starknet::interface] +trait ILizInventory { + fn add_stock(ref self: TContractState, product: felt252, new_stock: u32); + fn purchase(ref self: TContractState, product: felt252, quantity: u32); + fn get_stock(self: @TContractState, product: felt252) -> u32; + fn get_owner(self: @TContractState) -> ContractAddress; +} + +#[starknet::contract] +mod LizInventory { + use starknet::ContractAddress; + use starknet::get_caller_address; + use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess, StoragePathEntry, Map, StorageMapReadAccess, StorageMapWriteAccess}; + + #[storage] + struct Storage { + contract_owner: ContractAddress, + inventory: Map, + } + + #[constructor] + fn constructor(ref self: ContractState, owner: ContractAddress) { + self.contract_owner.write(owner); + } + + + #[abi(embed_v0)] + impl LizInventoryImpl of super::ILizInventory { + fn add_stock(ref self: ContractState, product: felt252, new_stock: u32) { + // Only owner can call this + let caller = get_caller_address(); + let owner = self.contract_owner.read(); + assert(caller == owner, 'Only owner can add stock'); + + // Add new_stock to existing stock in inventory + let current_stock = self.inventory.entry(product).read(); + let updated_stock = current_stock + new_stock; + self.inventory.entry(product).write(updated_stock); + } + + fn purchase(ref self: ContractState, product: felt252, quantity: u32) { + // Anybody can call this + // Subtract quantity from stock in inventory + let current_stock = self.inventory.entry(product).read(); + assert(current_stock >= quantity, 'Insufficient stock'); + + let updated_stock = current_stock - quantity; + self.inventory.entry(product).write(updated_stock); + } + + fn get_stock(self: @ContractState, product: felt252) -> u32 { + // Returns product stock in inventory + self.inventory.entry(product).read() + } + + fn get_owner(self: @ContractState) -> ContractAddress { + self.contract_owner.read() + } + } +} + +#[cfg(test)] +mod test { + use starknet::ContractAddress; + use super::LizInventory; + use super::ILizInventoryDispatcher; + use super::ILizInventoryDispatcherTrait; + use snforge_std::{declare, ContractClassTrait, DeclareResultTrait, start_cheat_caller_address, stop_cheat_caller_address}; + + #[test] + fn test_owner() { + let owner: ContractAddress = 'Elizabeth'.try_into().unwrap(); + let dispatcher = deploy_contract(); + + // Check that contract owner is set + let contract_owner = dispatcher.get_owner(); + assert(contract_owner == owner, 'Elizabeth should be the owner'); + } + + #[test] + fn test_stock() { + let dispatcher = deploy_contract(); + let owner = util_felt_addr('Elizabeth'); + + // Call contract as owner + start_cheat_caller_address(dispatcher.contract_address, owner); + + // Add stock + dispatcher.add_stock('Nano', 10); + let stock = dispatcher.get_stock('Nano'); + assert(stock == 10, 'stock should be 10'); + + dispatcher.add_stock('Nano', 15); + let stock = dispatcher.get_stock('Nano'); + assert(stock == 25, 'stock should be 25'); + + stop_cheat_caller_address(dispatcher.contract_address); + } + + #[test] + fn test_stock_purchase() { + let owner = util_felt_addr('Elizabeth'); + let dispatcher = deploy_contract(); + // Call contract as owner + start_cheat_caller_address(dispatcher.contract_address, owner); + + // Add stock + dispatcher.add_stock('Nano', 10); + let stock = dispatcher.get_stock('Nano'); + assert(stock == 10, 'stock should be 10'); + + // Call contract as different address + stop_cheat_caller_address(dispatcher.contract_address); + start_cheat_caller_address(dispatcher.contract_address, 0.try_into().unwrap()); + + dispatcher.purchase('Nano', 2); + let stock = dispatcher.get_stock('Nano'); + assert(stock == 8, 'stock should be 8'); + + stop_cheat_caller_address(dispatcher.contract_address); + } + + #[test] + #[should_panic] + fn test_set_stock_fail() { + let dispatcher = deploy_contract(); + // Try to add stock, should panic to pass test! + dispatcher.add_stock('Nano', 20); + } + + #[test] + #[should_panic] + fn test_purchase_out_of_stock() { + let dispatcher = deploy_contract(); + // Purchase out of stock + dispatcher.purchase('Nano', 2); + } + + fn util_felt_addr(addr_felt: felt252) -> ContractAddress { + addr_felt.try_into().unwrap() + } + + fn deploy_contract() -> ILizInventoryDispatcher { + let owner: felt252 = 'Elizabeth'; + let mut calldata = ArrayTrait::new(); + calldata.append(owner); + + let contract = declare("LizInventory").unwrap().contract_class(); + let (contract_address, _) = contract.deploy(@calldata).unwrap(); + ILizInventoryDispatcher { contract_address } + } +} diff --git a/solutions/starknet/components/starknet6.cairo b/solutions/starknet/components/starknet6.cairo new file mode 100644 index 000000000..d7dc3e20b --- /dev/null +++ b/solutions/starknet/components/starknet6.cairo @@ -0,0 +1,90 @@ +// This code is using Starknet components to make a reusable owner feature. +// This should add OwnableComponent containing functionality which any contracts can include. +// But something is fishy here as this component is not working, can you find the error and make the tests pass? + +// I AM NOT DONE + +use starknet::ContractAddress; + +#[starknet::interface] +trait IOwnable { + fn owner(self: @TContractState) -> ContractAddress; + fn set_owner(ref self: TContractState, new_owner: ContractAddress); +} + +mod OwnableComponent { + use starknet::ContractAddress; + use super::IOwnable; + + #[storage] + struct Storage { + owner: ContractAddress, + } + + #[embeddable_as(Ownable)] + impl OwnableImpl< + TContractState, +HasComponent + > of IOwnable> { + fn owner(self: @ComponentState) -> ContractAddress { + self.owner.read() + } + fn set_owner(ref self: ComponentState, new_owner: ContractAddress) { + self.owner.write(new_owner); + } + } +} + +#[starknet::contract] +mod OwnableCounter { + use starknet::ContractAddress; + use super::OwnableComponent; + + component!(path: OwnableComponent, storage: ownable, event: OwnableEvent); + + #[abi(embed_v0)] + impl OwnableImpl = OwnableComponent::Ownable; + + #[event] + #[derive(Drop, starknet::Event)] + enum Event { + #[flat] + OwnableEvent: OwnableComponent::Event, + } + #[storage] + struct Storage { + counter: u128, + #[substorage(v0)] + ownable: OwnableComponent::Storage, + } +} + +#[cfg(test)] +mod tests { + use snforge_std::{declare, ContractClassTrait, DeclareResultTrait}; + use starknet::{contract_address_const, ContractAddress}; + use super::IOwnableDispatcher; + + fn deploy_ownable_counter() -> IOwnableDispatcher { + let contract = declare("OwnableCounter").unwrap().contract_class(); + let (contract_address, _) = contract.deploy(@array![]).unwrap(); + IOwnableDispatcher { contract_address } + } + + #[test] + fn test_contract_read() { + let dispatcher = deploy_ownable_counter(); + let address_0 = 0; + dispatcher.set_owner(address_0.try_into().unwrap()); + assert(address_0.try_into().unwrap() == dispatcher.owner(), 'Some fuck up happened'); + } + + #[test] + #[should_panic] + fn test_contract_read_fail() { + let dispatcher = deploy_ownable_counter(); + let address_0 = 0; + let address_1 = 1; + dispatcher.set_owner(address_0.try_into().unwrap()); + assert(address_1.try_into().unwrap() == dispatcher.owner(), 'Some fuck up happened'); + } +} diff --git a/solutions/starknet/interoperability/starknet5.cairo b/solutions/starknet/interoperability/starknet5.cairo new file mode 100644 index 000000000..43ca13f09 --- /dev/null +++ b/solutions/starknet/interoperability/starknet5.cairo @@ -0,0 +1,121 @@ +// Address all the TODOs to make the tests pass! + +// I AM NOT DONE + +#[starknet::interface] +trait IContractA { + fn set_value(ref self: TContractState, value: u128) -> bool; + fn get_value(self: @TContractState) -> u128; +} + + +#[starknet::contract] +mod ContractA { + use starknet::ContractAddress; + use super::IContractBDispatcher; + use super::IContractBDispatcherTrait; + use starknet::storage::*; + + #[storage] + struct Storage { + contract_b: ContractAddress, + value: u128, + } + + #[constructor] + fn constructor(ref self: ContractState, contract_b: ContractAddress) { + self.contract_b.write(contract_b) + } + + #[abi(embed_v0)] + impl ContractAImpl of super::IContractA { + fn set_value(ref self: ContractState, value: u128) -> bool { + // TODO: check if contract_b is enabled. + // If it is, set the value and return true. Otherwise, return false. + let contract_b = self.contract_b.read(); + let contract_b_dispatcher = IContractBDispatcher { contract_address: contract_b }; + if contract_b_dispatcher.is_enabled() { + self.value.write(value); + return true; + } + return false; + } + + fn get_value(self: @ContractState) -> u128 { + self.value.read() + } + } +} + +#[starknet::interface] +trait IContractB { + fn enable(ref self: TContractState); + fn disable(ref self: TContractState); + fn is_enabled(self: @TContractState) -> bool; +} + +#[starknet::contract] +mod ContractB { + use starknet::storage::*; + + #[storage] + struct Storage { + enabled: bool + } + + #[constructor] + fn constructor(ref self: ContractState) {} + + #[abi(embed_v0)] + impl ContractBImpl of super::IContractB { + fn enable(ref self: ContractState) { + self.enabled.write(true); + } + + fn disable(ref self: ContractState) { + self.enabled.write(false); + } + + fn is_enabled(self: @ContractState) -> bool { + self.enabled.read() + } + } +} + +#[cfg(test)] +mod test { + use snforge_std::{declare, ContractClassTrait, DeclareResultTrait}; + use starknet::ContractAddress; + use super::{IContractBDispatcher, IContractADispatcher, IContractADispatcherTrait, IContractBDispatcherTrait}; + + + fn deploy_contract_b() -> IContractBDispatcher { + let contract = declare("ContractB").unwrap().contract_class(); + let (contract_address, _) = contract.deploy(@array![]).unwrap(); + IContractBDispatcher { contract_address } + } + + fn deploy_contract_a(contract_b_address: ContractAddress) -> IContractADispatcher { + let contract = declare("ContractA").unwrap().contract_class(); + let constructor_calldata = array![contract_b_address.into()]; + let (contract_address, _) = contract.deploy(@constructor_calldata).unwrap(); + IContractADispatcher { contract_address } + } + + #[test] + fn test_interoperability() { + // Deploy ContractB + let contract_b = deploy_contract_b(); + + // Deploy ContractA + let contract_a = deploy_contract_a(contract_b.contract_address); + + // Enable contract_b to make the test pass + contract_b.enable(); + + // Tests + assert(contract_a.set_value(300) == true, 'Could not set value'); + assert(contract_a.get_value() == 300, 'Value was not set'); + assert(contract_b.is_enabled() == true, 'Contract b is not enabled'); + } +} diff --git a/src/exercise.rs b/src/exercise.rs index 013778455..a13f9f5c4 100755 --- a/src/exercise.rs +++ b/src/exercise.rs @@ -2,27 +2,15 @@ use regex::Regex; use serde::Deserialize; use std::fmt::{self, Display, Formatter}; -use std::fs::{remove_file, File}; +use std::fs::File; use std::io::Read; use std::path::PathBuf; -use std::process::{self}; use crate::scarb::{scarb_build, scarb_run, scarb_test}; const I_AM_DONE_REGEX: &str = r"(?m)^\s*///?\s*I\s+AM\s+NOT\s+DONE"; const CONTEXT: usize = 2; -// Get a temporary file name that is hopefully unique -#[inline] -fn temp_file() -> String { - let thread_id: String = format!("{:?}", std::thread::current().id()) - .chars() - .filter(|c| c.is_alphanumeric()) - .collect(); - - format!("./temp_{}_{thread_id}", process::id()) -} - // The mode of the exercise. #[derive(Deserialize, Copy, Clone, Debug)] #[serde(rename_all = "lowercase")] @@ -75,22 +63,6 @@ pub struct ContextLine { pub important: bool, } -// A representation of an already executed binary -#[derive(Debug)] -pub struct ExerciseOutput { - // The textual contents of the standard output of the binary - pub stdout: String, - // The textual contents of the standard error of the binary - pub stderr: String, -} - -struct FileHandle; - -impl Drop for FileHandle { - fn drop(&mut self) { - clean(); - } -} impl Exercise { pub fn build(&self) -> anyhow::Result { @@ -164,11 +136,6 @@ impl Display for Exercise { } } -#[inline] -fn clean() { - let _ignored = remove_file(temp_file()); -} - #[cfg(test)] mod test { use super::*; diff --git a/src/lib.cairo b/src/lib.cairo new file mode 100644 index 000000000..fd56defca --- /dev/null +++ b/src/lib.cairo @@ -0,0 +1,10 @@ +mod exercises { + mod starknet { + mod components { + mod starknet6; + } + mod interoperability { + mod starknet5; + } + } +} diff --git a/src/main.rs b/src/main.rs index bcdc661c3..250003db8 100755 --- a/src/main.rs +++ b/src/main.rs @@ -79,6 +79,8 @@ struct RunArgs { #[argh(positional)] /// the name of the exercise name: String, + #[argh(switch, short = 's', description = "use solutions directory")] + solutions: bool, } #[derive(FromArgs, PartialEq, Debug)] @@ -230,6 +232,9 @@ fn main() { } Subcommands::Run(subargs) => { + if subargs.solutions { + exercises = exercises_solution(exercises); + } let exercise = find_exercise(&subargs.name, &exercises); run(exercise).unwrap_or_else(|_| std::process::exit(1)); @@ -479,34 +484,34 @@ const FINISH_LINE: &str = r#"+-------------------------------------------------- | You made it to the finish line! | +-------------------------- ------------------------+ - - @@@@@@@@@@@@@@& - #@@@@@@@@@@@@@@@@@@@@@@@@@@@/ - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@( - &@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@( - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - @@@@@@@@@@@*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - &@@@@@@@@@@@ @@@@@@@@@@@@@@@& @@@@@@@@ - @@@@@@@@@@, *@@@@@@@@@ @@@@@@& - @@@@@@@@@@@@@@ @@@@@@@@@@ *@@@@@& - /@@@@@@@@@@@@@@@-@@@@@@@@@ .*********/@@@@@@@@ - @@@@@@@@@@@@@@@@@@@@@@@@ **********@@@@@@@@@@@@ - @@@@@@@@@@@@@@@@@@@@@@ *********@@@@@@@@@@@@@@ - @@@@@@@@@@@@@@@@@@@@ *********@@@@@@@@@@@@@@@@ - @@@@@@@@@@@@@@@@* ,********&@@@@@@@@@@@@@@@@@ - @@@@@@ *********/@@@@@@@@@@@@@@@@@@@ - ,@@@@@@( *********/@@@@@@@@@@@@@@@@@@@@ - @@@@@@@@/, .**********@@@@@@@%**%@@@@@@@@@@@( - @@@@@@@@@@*****,,,**************@@@@@@@@&******%@@@@@@@@( - ,@@@@@@@@@@@@/************(@@@@@@@@@@@@@******@@@@@@@@ - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@& - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - /@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - *@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - .@@@@@@@@@@@@@@@@@@@@@@@@@@@ - .@@@@@@@@@@@@& - - + + @@@@@@@@@@@@@@& + #@@@@@@@@@@@@@@@@@@@@@@@@@@@/ + @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@( + &@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@( + @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + &@@@@@@@@@@@ @@@@@@@@@@@@@@@& @@@@@@@@ + @@@@@@@@@@, *@@@@@@@@@ @@@@@@& + @@@@@@@@@@@@@@ @@@@@@@@@@ *@@@@@& + /@@@@@@@@@@@@@@@-@@@@@@@@@ .*********/@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@@@ **********@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@ *********@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@ *********@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@* ,********&@@@@@@@@@@@@@@@@@ + @@@@@@ *********/@@@@@@@@@@@@@@@@@@@ + ,@@@@@@( *********/@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@/, .**********@@@@@@@%**%@@@@@@@@@@@( + @@@@@@@@@@*****,,,**************@@@@@@@@&******%@@@@@@@@( + ,@@@@@@@@@@@@/************(@@@@@@@@@@@@@******@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@& + @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + /@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + *@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + .@@@@@@@@@@@@@@@@@@@@@@@@@@@ + .@@@@@@@@@@@@& + + We hope you enjoyed learning about Cairo and Starknet! If you noticed any issues, please don't hesitate to report them to our repo. diff --git a/src/scarb.rs b/src/scarb.rs index 6abd1e500..9055b0c6b 100644 --- a/src/scarb.rs +++ b/src/scarb.rs @@ -1,19 +1,5 @@ -use anyhow::Context; -use cairo_lang_runner::{RunResultValue, SierraCasmRunner, StarknetState}; -use cairo_lang_sierra::program::VersionedProgram; -use cairo_lang_test_plugin::{TestCompilation, TestCompilationMetadata}; -use cairo_lang_test_runner::{CompiledTestRunner, RunProfilerConfig, TestRunConfig}; -use camino::Utf8PathBuf; use console::style; -use std::{env::current_dir, fs, path::PathBuf}; - -use itertools::Itertools; -use scarb::{ - core::{Config, TargetKind}, - ops::{self, collect_metadata, CompileOpts, FeaturesOpts, FeaturesSelector, MetadataOptions}, -}; - -const AVAILABLE_GAS: usize = 999999999; +use std::{env::current_dir, fs, path::PathBuf, process::Command}; // Prepares testing crate // Copies the exercise file into testing crate @@ -33,26 +19,31 @@ pub fn prepare_crate_for_exercise(file_path: &PathBuf) -> PathBuf { crate_path } -// Builds the testing crate with scarb +// Builds the testing crate with scarb CLI pub fn scarb_build(file_path: &PathBuf) -> anyhow::Result { let crate_path = prepare_crate_for_exercise(file_path); - let config = scarb_config(crate_path); - match compile(&config, false) { - Ok(_) => Ok("".into()), - Err(_) => anyhow::bail!("Couldn't build the exercise..."), + let output = Command::new("scarb") + .args(["build"]) + .current_dir(&crate_path) + .env("FORCE_COLOR", "1") + .env("CLICOLOR_FORCE", "1") + .output() + .map_err(|e| anyhow::anyhow!("Failed to execute scarb build: {}", e))?; + + if !output.status.success() { + let stderr = String::from_utf8_lossy(&output.stderr); + let stdout = String::from_utf8_lossy(&output.stdout); + anyhow::bail!("Scarb build failed:\nstdout:\n{}\nstderr:\n{}", stdout, stderr); } + + let stdout = String::from_utf8_lossy(&output.stdout); + Ok(stdout.to_string()) } -// Runs the crate with scarb +// Runs the crate with scarb CLI pub fn scarb_run(file_path: &PathBuf) -> anyhow::Result { let crate_path = prepare_crate_for_exercise(file_path); - let config = scarb_config(crate_path); - - let ws = ops::read_workspace(config.manifest_path(), &config)?; - - // Compile before running tests, with test targets true - compile(&config, false)?; println!( " {} {}\n", @@ -60,205 +51,42 @@ pub fn scarb_run(file_path: &PathBuf) -> anyhow::Result { file_path.to_str().unwrap() ); - let metadata = collect_metadata( - &MetadataOptions { - version: 1, - no_deps: false, - features: FeaturesOpts { - features: FeaturesSelector::AllFeatures, - no_default_features: false, - }, - }, - &ws, - )?; - - let profile = "dev"; - let default_target_dir = metadata.runtime_manifest.join("target"); - - let target_dir = metadata - .target_dir - .clone() - .unwrap_or(default_target_dir) - .join(profile); - - // Process 'exercise_crate' targets - // Largely same as this - // https://github.com/software-mansion/scarb/blob/v2.5.3/extensions/scarb-cairo-run/src/main.rs#L61 - for package in metadata.packages.iter() { - if package.name != "exercise_crate" { - continue; - } - // Loop through targets and run compiled file tests - for target in package.targets.iter() { - // Skip test targets - if target.kind == "test" { - continue; - } - - let file_path = target_dir.join(format!("{}.sierra.json", target.name.clone())); - - assert!( - file_path.exists(), - "File {file_path} missing, please compile the project." - ); - - let sierra_program = serde_json::from_str::( - &fs::read_to_string(file_path.clone()) - .with_context(|| format!("failed to read Sierra file: {file_path}"))?, - ) - .with_context(|| format!("failed to deserialize Sierra program: {file_path}"))? - .into_v1() - .with_context(|| format!("failed to load Sierra program: {file_path}"))?; - - let runner = SierraCasmRunner::new( - sierra_program.program, - Some(Default::default()), - Default::default(), - None, - )?; - - let result = runner - .run_function_with_starknet_context( - runner.find_function("::main")?, - &[], - Some(AVAILABLE_GAS), - StarknetState::default(), - ) - .context("failed to run the function")?; - - return match result.value { - RunResultValue::Success(return_val) => { - Ok(return_val.iter().map(|el| el.to_string()).join(",")) - } - RunResultValue::Panic(error) => { - anyhow::bail!(format!("error running the code, {:?}", error)) - } - }; - } + let output = Command::new("scarb") + .args(["cairo-run"]) + .current_dir(&crate_path) + .env("FORCE_COLOR", "1") + .env("CLICOLOR_FORCE", "1") + .output() + .map_err(|e| anyhow::anyhow!("Failed to execute scarb cairo-run: {}", e))?; + + if !output.status.success() { + let stderr = String::from_utf8_lossy(&output.stderr); + let stdout = String::from_utf8_lossy(&output.stdout); + anyhow::bail!("Scarb cairo-run failed:\nstdout:\n{}\nstderr:\n{}", stdout, stderr); } - Ok("".into()) + let stdout = String::from_utf8_lossy(&output.stdout); + Ok(stdout.to_string()) } -// Runs tests on the testing crate with scarb +// Runs tests on the testing crate with scarb CLI pub fn scarb_test(file_path: &PathBuf) -> anyhow::Result { let crate_path = prepare_crate_for_exercise(file_path); - let config = scarb_config(crate_path); - - let ws = ops::read_workspace(config.manifest_path(), &config)?; - - // Compile before running tests, with test targets true - compile(&config, true)?; - let metadata = collect_metadata( - &MetadataOptions { - version: 1, - no_deps: false, - features: FeaturesOpts { - features: FeaturesSelector::AllFeatures, - no_default_features: false, - }, - }, - &ws, - ) - .unwrap(); - - let profile = "dev"; - let default_target_dir = metadata.runtime_manifest.join("target"); - - let target_dir = metadata - .target_dir - .clone() - .unwrap_or(default_target_dir) - .join(profile); - - // Loop through packages, but only process 'exercise_crate' - // Largely same as this - // https://github.com/software-mansion/scarb/blob/v2.6.2/extensions/scarb-cairo-test/src/main.rs#L54 - for package in metadata.packages.iter() { - if package.name != "exercise_crate" { - continue; - } - // Loop through targets and run compiled file tests - for target in package.targets.iter() { - if target.kind != "test" { - continue; - } - - let test_compilation = deserialize_test_compilation(&target_dir, target.name.clone())?; - let config = TestRunConfig { - filter: "".into(), - include_ignored: false, - ignored: false, - run_profiler: RunProfilerConfig::None, - gas_enabled: true, - print_resource_usage: false, - }; - let runner = CompiledTestRunner::new(test_compilation, config); - runner.run(None)?; - println!(); - } + let output = Command::new("scarb") + .args(["test"]) + .current_dir(&crate_path) + .env("FORCE_COLOR", "1") + .env("CLICOLOR_FORCE", "1") + .output() + .map_err(|e| anyhow::anyhow!("Failed to execute scarb test: {}", e))?; + + if !output.status.success() { + let stderr = String::from_utf8_lossy(&output.stderr); + let stdout = String::from_utf8_lossy(&output.stdout); + anyhow::bail!("Scarb test failed:\nstdout:\n{}\nstderr:\n{}", stdout, stderr); } - anyhow::Ok("".into()) -} - -fn deserialize_test_compilation( - target_dir: &Utf8PathBuf, - name: String, -) -> anyhow::Result { - let file_path = target_dir.join(format!("{}.test.json", name)); - let test_comp_metadata = serde_json::from_str::( - &fs::read_to_string(file_path.clone()) - .with_context(|| format!("failed to read file: {file_path}"))?, - ) - .with_context(|| format!("failed to deserialize compiled tests metadata file: {file_path}"))?; - - let file_path = target_dir.join(format!("{}.test.sierra.json", name)); - let sierra_program = serde_json::from_str::( - &fs::read_to_string(file_path.clone()) - .with_context(|| format!("failed to read file: {file_path}"))?, - ) - .with_context(|| format!("failed to deserialize compiled tests sierra file: {file_path}"))?; - - Ok(TestCompilation { - sierra_program: sierra_program.into_v1()?, - metadata: test_comp_metadata, - }) -} - -// Prepares scarb config for exercise runner crate -pub fn scarb_config(crate_path: PathBuf) -> Config { - let path = Utf8PathBuf::from_path_buf(crate_path.join(PathBuf::from("Scarb.toml"))).unwrap(); - - Config::builder(path).build().unwrap() -} - -// Compiles runner crate for build/test exercises -pub fn compile(config: &Config, test_targets: bool) -> anyhow::Result<()> { - let ws = ops::read_workspace(config.manifest_path(), config)?; - let opts: CompileOpts = match test_targets { - false => CompileOpts { - include_target_names: vec![], - include_target_kinds: vec![], - exclude_target_kinds: vec![TargetKind::TEST], - features: FeaturesOpts { - features: FeaturesSelector::AllFeatures, - no_default_features: false, - }, - }, - true => CompileOpts { - include_target_names: vec![], - include_target_kinds: vec![TargetKind::TEST], - exclude_target_kinds: vec![], - features: FeaturesOpts { - features: FeaturesSelector::AllFeatures, - no_default_features: false, - }, - }, - }; - - let packages = ws.members().map(|p| p.id).collect(); - - ops::compile(packages, opts, &ws) + let stdout = String::from_utf8_lossy(&output.stdout); + Ok(stdout.to_string()) } diff --git a/src/utils.rs b/src/utils.rs index f85bde9d3..7b8539462 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -57,7 +57,7 @@ pub fn test_exercise(exercise: &Exercise) -> Result { } pub fn print_exercise_output(exercise_output: String) { - if exercise_output.len() > 0 { + if !exercise_output.is_empty() { println!(" {} {exercise_output}", style("Output").green().bold()); } } diff --git a/tests/fixture/cairo/runner-crate/Scarb.lock b/tests/fixture/cairo/runner-crate/Scarb.lock index 34fdb7e85..f603c1903 100644 --- a/tests/fixture/cairo/runner-crate/Scarb.lock +++ b/tests/fixture/cairo/runner-crate/Scarb.lock @@ -2,5 +2,23 @@ version = 1 [[package]] -name = "exercise_crate" +name = "runner_crate" version = "0.1.0" +dependencies = [ + "snforge_std", +] + +[[package]] +name = "snforge_scarb_plugin" +version = "0.44.0" +source = "registry+https://scarbs.xyz/" +checksum = "sha256:ec8c7637b33392a53153c1e5b87a4617ddcb1981951b233ea043cad5136697e2" + +[[package]] +name = "snforge_std" +version = "0.44.0" +source = "registry+https://scarbs.xyz/" +checksum = "sha256:d4affedfb90715b1ac417b915c0a63377ae6dd69432040e5d933130d65114702" +dependencies = [ + "snforge_scarb_plugin", +] diff --git a/tests/fixture/cairo/runner-crate/Scarb.toml b/tests/fixture/cairo/runner-crate/Scarb.toml index 4ca173cb6..4b848bfd9 100644 --- a/tests/fixture/cairo/runner-crate/Scarb.toml +++ b/tests/fixture/cairo/runner-crate/Scarb.toml @@ -1,9 +1,21 @@ [package] -name = "exercise_crate" +name = "runner_crate" version = "0.1.0" +edition = "2024_07" -# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html [dependencies] -starknet = "2.8.0" -cairo_test = "2.8.0" +starknet = "2.11.4" + +[dev-dependencies] +snforge_std = "0.44.0" +assert_macros = "2.11.4" + +[[target.starknet-contract]] +sierra = true + +[scripts] +test = "snforge test" + +[tool.scarb] +allow-prebuilt-plugins = ["snforge_std"] diff --git a/tests/lib.cairo b/tests/lib.cairo new file mode 100644 index 000000000..bc801c7de --- /dev/null +++ b/tests/lib.cairo @@ -0,0 +1,8 @@ +mod starknet { + mod components { + mod test_starknet6; + } + mod interoperability { + mod test_starknet5; + } +} From c68a3859428736199a66fa121943f1d44ab9c3c7 Mon Sep 17 00:00:00 2001 From: enitrat Date: Mon, 16 Jun 2025 18:33:08 +0200 Subject: [PATCH 02/12] update cli --- .github/workflows/rust.yml | 2 ++ .gitignore | 1 + 2 files changed, 3 insertions(+) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 8b95327a7..ce989d799 100755 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -16,6 +16,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup Rust v1.80.1 run: rustup default 1.80.1 + - name: Install all Cairo tools + run: curl --proto '=https' --tlsv1.2 -sSf https://sh.starkup.sh | sh -s -- --version-set latest - name: Build run: cargo build --verbose - name: Run tests diff --git a/.gitignore b/.gitignore index 5bdac39a9..41981ddd2 100755 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ rust-project.json *.iml *.o **/runner-crate/src/lib.cairo +**/.snfoundry_cache From a4c84b3dda1c24a444b36cf26704d36b591095ce Mon Sep 17 00:00:00 2001 From: enitrat Date: Fri, 11 Jul 2025 15:02:25 +0100 Subject: [PATCH 03/12] add cfg(test) attr to tests --- exercises/arrays/arrays1.cairo | 2 +- exercises/arrays/arrays2.cairo | 3 ++- exercises/arrays/arrays3.cairo | 1 + exercises/dict/dict1.cairo | 3 +-- exercises/dict/dict2.cairo | 6 +++--- exercises/dict/dict3.cairo | 6 +++--- exercises/enums/enums3.cairo | 1 + exercises/loops/loops1.cairo | 2 +- exercises/loops/loops2.cairo | 2 +- exercises/modules/modules1.cairo | 1 + exercises/modules/modules2.cairo | 1 + exercises/move_semantics/move_semantics5.cairo | 1 + exercises/operations/operations1.cairo | 2 +- exercises/operations/operations2.cairo | 4 ++++ exercises/options/options1.cairo | 2 ++ exercises/options/options2.cairo | 1 + exercises/options/options3.cairo | 6 +++--- exercises/primitive_types/primitive_types4.cairo | 4 ++++ exercises/quizs/quizs1.cairo | 1 + exercises/starknet/basics/starknet1.cairo | 6 ++---- exercises/starknet/basics/starknet2.cairo | 8 +++----- exercises/structs/structs1.cairo | 1 + exercises/structs/structs2.cairo | 2 +- exercises/structs/structs3.cairo | 5 ++++- exercises/traits/traits1.cairo | 1 + exercises/traits/traits2.cairo | 5 +++-- exercises/traits/traits3.cairo | 1 + 27 files changed, 49 insertions(+), 29 deletions(-) diff --git a/exercises/arrays/arrays1.cairo b/exercises/arrays/arrays1.cairo index 49e6da223..265213968 100644 --- a/exercises/arrays/arrays1.cairo +++ b/exercises/arrays/arrays1.cairo @@ -12,10 +12,10 @@ fn create_array() -> Array { // Don't change anything in the test +#[cfg(test)] #[test] fn test_array_len() { let mut a = create_array(); assert(a.len() == 3, 'Array length is not 3'); assert(a.pop_front().unwrap() == 0, 'First element is not 0'); } - diff --git a/exercises/arrays/arrays2.cairo b/exercises/arrays/arrays2.cairo index 79f987873..57b625052 100644 --- a/exercises/arrays/arrays2.cairo +++ b/exercises/arrays/arrays2.cairo @@ -15,16 +15,17 @@ fn remove_element_from_array( ) { //TODO something to do here...Is there an array method I can use? } +#[cfg(test)] #[test] fn test_arrays2() { let mut a = create_array(); assert(*a.at(0) == 42, 'First element is not 42'); } +#[cfg(test)] #[test] fn test_arrays2_empty() { let mut a = create_array(); remove_element_from_array(ref a); assert(a.len() == 0, 'Array length is not 0'); } - diff --git a/exercises/arrays/arrays3.cairo b/exercises/arrays/arrays3.cairo index aad0822e0..58dc3170a 100644 --- a/exercises/arrays/arrays3.cairo +++ b/exercises/arrays/arrays3.cairo @@ -12,6 +12,7 @@ fn create_array() -> Array { } +#[cfg(test)] #[test] fn test_arrays3() { let mut a = create_array(); diff --git a/exercises/dict/dict1.cairo b/exercises/dict/dict1.cairo index ffb36040e..6e5a9f5df 100644 --- a/exercises/dict/dict1.cairo +++ b/exercises/dict/dict1.cairo @@ -16,12 +16,11 @@ fn create_dictionary() -> Felt252Dict { // Don't change anything in the test +#[cfg(test)] #[test] -#[available_gas(200000)] fn test_dict() { let mut dict = create_dictionary(); assert(dict.get('A') == 1, 'First element is not 1'); assert(dict.get('B') == 2, 'Second element is not 2'); assert(dict.get('bob') == 3, 'Third element is not 3'); } - diff --git a/exercises/dict/dict2.cairo b/exercises/dict/dict2.cairo index 91585a353..fe51655c8 100644 --- a/exercises/dict/dict2.cairo +++ b/exercises/dict/dict2.cairo @@ -12,8 +12,8 @@ fn multiply_element_by_10(ref dict: Felt252Dict, n: usize) { } // Don't change anything in the test +#[cfg(test)] #[test] -#[available_gas(2000000000)] fn test_3() { let mut dict: Felt252Dict = Default::default(); dict.insert(0, 1); @@ -27,8 +27,8 @@ fn test_3() { assert(dict.get(2) == 30, 'Third element is not 30'); } +#[cfg(test)] #[test] -#[available_gas(200000000)] fn test_4() { let mut dict: Felt252Dict = Default::default(); dict.insert(0, 1); @@ -41,4 +41,4 @@ fn test_4() { assert(dict.get(2) == 50, 'First element is not 50'); assert(dict.get(3) == 100, 'First element is not 100'); -} \ No newline at end of file +} diff --git a/exercises/dict/dict3.cairo b/exercises/dict/dict3.cairo index f336c731d..5f32ed874 100644 --- a/exercises/dict/dict3.cairo +++ b/exercises/dict/dict3.cairo @@ -20,7 +20,7 @@ impl TeamImpl of TeamTrait { } fn get_level(ref self: Team, name: felt252) -> usize { - //TODO + //TODO } fn add_player(ref self: Team, name: felt252, level: usize) -> () { @@ -37,8 +37,8 @@ impl TeamImpl of TeamTrait { } +#[cfg(test)] #[test] -#[available_gas(200000)] fn test_add_player() { let mut team = TeamTrait::new(); team.add_player('bob', 10); @@ -49,8 +49,8 @@ fn test_add_player() { assert(team.get_level('alice') == 20, 'Wrong level'); } +#[cfg(test)] #[test] -#[available_gas(200000)] fn test_level_up() { let mut team = TeamTrait::new(); team.add_player('bobby', 10); diff --git a/exercises/enums/enums3.cairo b/exercises/enums/enums3.cairo index 42741068c..fb4c759d7 100644 --- a/exercises/enums/enums3.cairo +++ b/exercises/enums/enums3.cairo @@ -52,6 +52,7 @@ impl StateImpl of StateTrait { } +#[cfg(test)] #[test] fn test_match_message_call() { let mut state = State { quit: false, position: Point { x: 0, y: 0 }, color: (0, 0, 0) }; diff --git a/exercises/loops/loops1.cairo b/exercises/loops/loops1.cairo index 673928cce..149bb4030 100644 --- a/exercises/loops/loops1.cairo +++ b/exercises/loops/loops1.cairo @@ -1,8 +1,8 @@ // I AM NOT DONE +#[cfg(test)] #[test] -#[available_gas(200000)] fn test_loop() { let mut counter = 0; //TODO make the test pass without changing any existing line diff --git a/exercises/loops/loops2.cairo b/exercises/loops/loops2.cairo index 53377e2c1..020e7a4a3 100644 --- a/exercises/loops/loops2.cairo +++ b/exercises/loops/loops2.cairo @@ -2,8 +2,8 @@ // I AM NOT DONE +#[cfg(test)] #[test] -#[available_gas(200000)] fn test_loop() { let mut counter = 0; diff --git a/exercises/modules/modules1.cairo b/exercises/modules/modules1.cairo index 9cc95052d..b9b8db835 100644 --- a/exercises/modules/modules1.cairo +++ b/exercises/modules/modules1.cairo @@ -10,6 +10,7 @@ mod restaurant { } } +#[cfg(test)] #[test] fn test_mod_fn() { // Fix this line to call take_order function from module diff --git a/exercises/modules/modules2.cairo b/exercises/modules/modules2.cairo index a7044146e..6ea8d4a09 100644 --- a/exercises/modules/modules2.cairo +++ b/exercises/modules/modules2.cairo @@ -36,6 +36,7 @@ mod order_utils { } } +#[cfg(test)] #[test] fn test_array() { let order1 = order_utils::dummy_phoned_order('John Doe'); diff --git a/exercises/move_semantics/move_semantics5.cairo b/exercises/move_semantics/move_semantics5.cairo index 814088391..55a14428f 100644 --- a/exercises/move_semantics/move_semantics5.cairo +++ b/exercises/move_semantics/move_semantics5.cairo @@ -3,6 +3,7 @@ // I AM NOT DONE +#[cfg(test)] #[test] fn main() { let mut a = ArrayTrait::new(); diff --git a/exercises/operations/operations1.cairo b/exercises/operations/operations1.cairo index 5ac41280c..0bd713fe2 100644 --- a/exercises/operations/operations1.cairo +++ b/exercises/operations/operations1.cairo @@ -12,6 +12,7 @@ fn poly(x: usize, y: usize) -> usize { // Do not change the test function +#[cfg(test)] #[test] fn test_poly() { let res = poly(5, 3); @@ -23,4 +24,3 @@ fn test_poly() { assert(res != 27, 'res != 27'); assert(res % 2 == 0, 'res %2 != 0'); } - diff --git a/exercises/operations/operations2.cairo b/exercises/operations/operations2.cairo index 475b8f5f0..075aa3eaf 100644 --- a/exercises/operations/operations2.cairo +++ b/exercises/operations/operations2.cairo @@ -25,6 +25,7 @@ fn multiplication(x: u64, y: u64) -> u64 { // Do not change the tests +#[cfg(test)] #[test] fn test_modulus() { let res = modulus(16, 2); @@ -34,6 +35,7 @@ fn test_modulus() { assert(res == 2, 'Error message'); } +#[cfg(test)] #[test] fn test_floor_division() { let res = floor_division(160, 2); @@ -43,6 +45,7 @@ fn test_floor_division() { assert(res == 5, 'Error message'); } +#[cfg(test)] #[test] fn test_mul() { let res = multiplication(16, 2); @@ -52,6 +55,7 @@ fn test_mul() { assert(res == 84, 'Error message'); } +#[cfg(test)] #[test] #[should_panic] fn test_u64_mul_overflow_1() { diff --git a/exercises/options/options1.cairo b/exercises/options/options1.cairo index 4e1c683da..1441deeed 100644 --- a/exercises/options/options1.cairo +++ b/exercises/options/options1.cairo @@ -13,6 +13,7 @@ fn maybe_icecream( } +#[cfg(test)] #[test] fn check_icecream() { assert(maybe_icecream(9).unwrap() == 5, 'err_1'); @@ -22,6 +23,7 @@ fn check_icecream() { assert(maybe_icecream(25).is_none(), 'err_5'); } +#[cfg(test)] #[test] fn raw_value() { // TODO: Fix this test. How do you get at the value contained in the Option? diff --git a/exercises/options/options2.cairo b/exercises/options/options2.cairo index b6f8260b8..e172368f8 100644 --- a/exercises/options/options2.cairo +++ b/exercises/options/options2.cairo @@ -2,6 +2,7 @@ // I AM NOT DONE +#[cfg(test)] #[test] fn test_options() { let target = 'starklings'; diff --git a/exercises/options/options3.cairo b/exercises/options/options3.cairo index 28b00749a..6b099127e 100644 --- a/exercises/options/options3.cairo +++ b/exercises/options/options3.cairo @@ -35,14 +35,14 @@ fn display_grades(student: @Student, index: usize) { // TODO: Modify the following lines so that if there is a grade for the course, it is printed. // Otherwise, print "No grade". - // + // println!("grade is {}", course.unwrap()); display_grades(student, index + 1); } +#[cfg(test)] #[test] -#[available_gas(20000000)] fn test_all_defined() { let courses = array![ Option::Some('A'), @@ -55,8 +55,8 @@ fn test_all_defined() { } +#[cfg(test)] #[test] -#[available_gas(20000000)] fn test_some_empty() { let courses = array![ Option::Some('A'), diff --git a/exercises/primitive_types/primitive_types4.cairo b/exercises/primitive_types/primitive_types4.cairo index 8cea9ce66..da397ba95 100644 --- a/exercises/primitive_types/primitive_types4.cairo +++ b/exercises/primitive_types/primitive_types4.cairo @@ -18,11 +18,13 @@ fn convert_to_felt(x: u8) -> felt252 { //TODO return x as a felt252. fn convert_felt_to_u8(x: felt252) -> u8 { //TODO return x as a u8. } +#[cfg(test)] #[test] fn test_sum_u8s() { assert(sum_u8s(1, 2_u8) == 3_u8, 'Something went wrong'); } +#[cfg(test)] #[test] fn test_sum_big_numbers() { //TODO modify this test to use the correct integer types. @@ -32,11 +34,13 @@ fn test_sum_big_numbers() { assert(sum_big_numbers(255_u8, 255_u8) == 510_u8, 'Something went wrong'); } +#[cfg(test)] #[test] fn test_convert_to_felt() { assert(convert_to_felt(1_u8) == 1, 'Type conversion went wrong'); } +#[cfg(test)] #[test] fn test_convert_to_u8() { assert(convert_felt_to_u8(1) == 1_u8, 'Type conversion went wrong'); diff --git a/exercises/quizs/quizs1.cairo b/exercises/quizs/quizs1.cairo index 44766a3ea..118778b12 100644 --- a/exercises/quizs/quizs1.cairo +++ b/exercises/quizs/quizs1.cairo @@ -11,6 +11,7 @@ fn calculate_price_of_apples{ } // Do not change the tests! +#[cfg(test)] #[test] fn verify_test() { let price1 = calculate_price_of_apples(35); diff --git a/exercises/starknet/basics/starknet1.cairo b/exercises/starknet/basics/starknet1.cairo index 86e9b9559..c538fe990 100644 --- a/exercises/starknet/basics/starknet1.cairo +++ b/exercises/starknet/basics/starknet1.cairo @@ -23,10 +23,8 @@ mod JoesContract { #[cfg(test)] mod test { - use super::JoesContract; - use super::IJoesContractDispatcher; - use super::IJoesContractDispatcherTrait; - use snforge_std::{declare, ContractClassTrait, DeclareResultTrait}; + use snforge_std::{ContractClassTrait, DeclareResultTrait, declare}; + use super::{IJoesContractDispatcher, IJoesContractDispatcherTrait, JoesContract}; #[test] fn test_contract_view() { diff --git a/exercises/starknet/basics/starknet2.cairo b/exercises/starknet/basics/starknet2.cairo index 8ed443e48..f50266d29 100644 --- a/exercises/starknet/basics/starknet2.cairo +++ b/exercises/starknet/basics/starknet2.cairo @@ -19,7 +19,7 @@ mod JillsContract { #[constructor] fn constructor( - ref self: ContractState, owner: ContractAddress + ref self: ContractState, owner: ContractAddress, ) { // TODO: Write `owner` to contract_owner storage } @@ -37,10 +37,8 @@ trait IJillsContract { #[cfg(test)] mod test { - use super::IJillsContractDispatcher; - use super::IJillsContractDispatcherTrait; - use super::JillsContract; - use snforge_std::{declare, ContractClassTrait, DeclareResultTrait}; + use snforge_std::{ContractClassTrait, DeclareResultTrait, declare}; + use super::{IJillsContractDispatcher, IJillsContractDispatcherTrait, JillsContract}; #[test] fn test_owner_setting() { diff --git a/exercises/structs/structs1.cairo b/exercises/structs/structs1.cairo index f363831c3..a600164c9 100644 --- a/exercises/structs/structs1.cairo +++ b/exercises/structs/structs1.cairo @@ -7,6 +7,7 @@ struct ColorStruct { // TODO: Something goes here } +#[cfg(test)] #[test] fn classic_c_structs() { // TODO: Instantiate a classic color struct! diff --git a/exercises/structs/structs2.cairo b/exercises/structs/structs2.cairo index f54251c39..78fb6b20c 100644 --- a/exercises/structs/structs2.cairo +++ b/exercises/structs/structs2.cairo @@ -24,6 +24,7 @@ fn create_order_template() -> Order { count: 0 } } +#[cfg(test)] #[test] fn test_your_order() { let order_template = create_order_template(); @@ -38,4 +39,3 @@ fn test_your_order() { assert(item_number == order_template.item_number, 'Wrong item number'); assert(count == 0, 'Wrong count'); } - diff --git a/exercises/structs/structs3.cairo b/exercises/structs/structs3.cairo index 3a692585c..acc7fc800 100644 --- a/exercises/structs/structs3.cairo +++ b/exercises/structs/structs3.cairo @@ -37,6 +37,7 @@ impl PackageImpl of PackageTrait { } } +#[cfg(test)] #[test] #[should_panic] fn fail_creating_weightless_package() { @@ -45,6 +46,7 @@ fn fail_creating_weightless_package() { PackageTrait::new(sender_country, recipient_country, 0); } +#[cfg(test)] #[test] fn create_international_package() { let sender_country = 'Spain'; @@ -55,6 +57,7 @@ fn create_international_package() { assert(package.is_international() == true, 'Not international'); } +#[cfg(test)] #[test] fn create_local_package() { let sender_country = 'Canada'; @@ -65,6 +68,7 @@ fn create_local_package() { assert(package.is_international() == false, 'International'); } +#[cfg(test)] #[test] fn calculate_transport_fees() { let sender_country = 'Spain'; @@ -76,4 +80,3 @@ fn calculate_transport_fees() { assert(package.get_fees(cents_per_gram) == 4500, 'Wrong fees'); } - diff --git a/exercises/traits/traits1.cairo b/exercises/traits/traits1.cairo index 8aec3803e..1d1dabde8 100644 --- a/exercises/traits/traits1.cairo +++ b/exercises/traits/traits1.cairo @@ -21,6 +21,7 @@ trait AnimalTrait { impl AnimalImpl of AnimalTrait { // TODO: implement the trait AnimalTrait for Animal } +#[cfg(test)] #[test] fn test_traits1() { // TODO make the test pass by creating two instances of Animal diff --git a/exercises/traits/traits2.cairo b/exercises/traits/traits2.cairo index 6c1977d89..ebe90222a 100644 --- a/exercises/traits/traits2.cairo +++ b/exercises/traits/traits2.cairo @@ -15,12 +15,12 @@ #[derive(Copy, Drop)] struct Cat { - noise: felt252, + noise: felt252, } #[derive(Copy, Drop)] struct Cow { - noise: felt252, + noise: felt252, } trait AnimalTrait { @@ -33,6 +33,7 @@ impl CatImpl of AnimalTrait { // TODO: implement the trait Animal for the t // TODO: implement the trait Animal for the type Cow +#[cfg(test)] #[test] fn test_traits2() { let kitty: Cat = AnimalTrait::new(); diff --git a/exercises/traits/traits3.cairo b/exercises/traits/traits3.cairo index 04979f72d..1ce21ad23 100644 --- a/exercises/traits/traits3.cairo +++ b/exercises/traits/traits3.cairo @@ -60,6 +60,7 @@ impl AnimalDogImpl of AnimalTrait { // TODO: implement DogTrait for the type Dog +#[cfg(test)] #[test] fn test_traits3() { // Don't modify this test! From 2f50cf3d9a23d20442d78de33fe551d90e6b59d4 Mon Sep 17 00:00:00 2001 From: enitrat Date: Fri, 11 Jul 2025 17:06:52 +0100 Subject: [PATCH 04/12] add all solutions and fix some exercises --- exercises/dict/dict1.cairo | 1 + exercises/dict/dict2.cairo | 2 + exercises/dict/dict3.cairo | 1 + exercises/modules/modules1.cairo | 4 +- exercises/modules/modules2.cairo | 24 +++--- .../move_semantics/move_semantics1.cairo | 8 +- .../move_semantics/move_semantics2.cairo | 6 +- .../move_semantics/move_semantics3.cairo | 4 +- .../move_semantics/move_semantics4.cairo | 4 +- exercises/options/options3.cairo | 43 +++------- .../primitive_types/primitive_types2.cairo | 4 +- exercises/starknet/components/starknet6.cairo | 9 +- runner-crate/Scarb.toml | 15 ++-- solutions/arrays/README.md | 12 +++ solutions/arrays/arrays1.cairo | 21 +++++ solutions/arrays/arrays2.cairo | 31 +++++++ solutions/arrays/arrays3.cairo | 19 +++++ solutions/dict/README.md | 6 ++ solutions/dict/dict1.cairo | 31 +++++++ solutions/dict/dict2.cairo | 45 ++++++++++ solutions/dict/dict3.cairo | 65 +++++++++++++++ solutions/enums/README.md | 9 ++ solutions/enums/enums1.cairo | 29 +++++++ solutions/enums/enums2.cairo | 60 ++++++++++++++ solutions/enums/enums3.cairo | 78 +++++++++++++++++ solutions/functions/README.md | 5 ++ solutions/functions/functions1.cairo | 9 ++ solutions/functions/functions2.cairo | 9 ++ solutions/functions/functions3.cairo | 9 ++ solutions/functions/functions4.cairo | 24 ++++++ solutions/if/README.md | 7 ++ solutions/if/if1.cairo | 25 ++++++ solutions/if/if2.cairo | 40 +++++++++ solutions/intro/intro1.cairo | 5 ++ solutions/intro/intro2.cairo | 5 ++ solutions/loops/README.md | 5 ++ solutions/loops/loops1.cairo | 16 ++++ solutions/loops/loops2.cairo | 18 ++++ solutions/modules/modules1.cairo | 29 +++++++ solutions/modules/modules2.cairo | 51 ++++++++++++ solutions/modules/readme.md | 76 +++++++++++++++++ solutions/move_semantics/README.md | 8 ++ .../move_semantics/move_semantics1.cairo | 23 +++++ .../move_semantics/move_semantics2.cairo | 26 ++++++ .../move_semantics/move_semantics3.cairo | 22 +++++ .../move_semantics/move_semantics4.cairo | 24 ++++++ .../move_semantics/move_semantics5.cairo | 22 +++++ .../move_semantics/move_semantics6.cairo | 26 ++++++ solutions/operations/README.md | 6 ++ solutions/operations/operations1.cairo | 26 ++++++ solutions/operations/operations2.cairo | 58 +++++++++++++ solutions/options/README.md | 13 +++ solutions/options/options1.cairo | 37 +++++++++ solutions/options/options2.cairo | 25 ++++++ solutions/options/options3.cairo | 52 ++++++++++++ solutions/primitive_types/README.md | 6 ++ .../primitive_types/primitive_types1.cairo | 18 ++++ .../primitive_types/primitive_types2.cairo | 82 ++++++++++++++++++ .../primitive_types/primitive_types3.cairo | 10 +++ .../primitive_types/primitive_types4.cairo | 48 +++++++++++ solutions/quizs/quizs1.cairo | 28 +++++++ solutions/starknet/components/starknet6.cairo | 13 +-- .../starknet/interoperability/starknet5.cairo | 2 +- solutions/structs/README.md | 17 ++++ solutions/structs/structs1.cairo | 21 +++++ solutions/structs/structs2.cairo | 39 +++++++++ solutions/structs/structs3.cairo | 78 +++++++++++++++++ solutions/traits/README.md | 11 +++ solutions/traits/traits1.cairo | 41 +++++++++ solutions/traits/traits2.cairo | 59 +++++++++++++ solutions/traits/traits3.cairo | 83 +++++++++++++++++++ solutions/variables/README.md | 13 +++ solutions/variables/variables1.cairo | 8 ++ solutions/variables/variables2.cairo | 11 +++ solutions/variables/variables3.cairo | 7 ++ solutions/variables/variables4.cairo | 8 ++ solutions/variables/variables5.cairo | 8 ++ solutions/variables/variables6.cairo | 8 ++ 78 files changed, 1777 insertions(+), 74 deletions(-) create mode 100644 solutions/arrays/README.md create mode 100644 solutions/arrays/arrays1.cairo create mode 100644 solutions/arrays/arrays2.cairo create mode 100644 solutions/arrays/arrays3.cairo create mode 100644 solutions/dict/README.md create mode 100644 solutions/dict/dict1.cairo create mode 100644 solutions/dict/dict2.cairo create mode 100644 solutions/dict/dict3.cairo create mode 100644 solutions/enums/README.md create mode 100644 solutions/enums/enums1.cairo create mode 100644 solutions/enums/enums2.cairo create mode 100644 solutions/enums/enums3.cairo create mode 100644 solutions/functions/README.md create mode 100644 solutions/functions/functions1.cairo create mode 100644 solutions/functions/functions2.cairo create mode 100644 solutions/functions/functions3.cairo create mode 100644 solutions/functions/functions4.cairo create mode 100644 solutions/if/README.md create mode 100644 solutions/if/if1.cairo create mode 100644 solutions/if/if2.cairo create mode 100644 solutions/intro/intro1.cairo create mode 100644 solutions/intro/intro2.cairo create mode 100644 solutions/loops/README.md create mode 100644 solutions/loops/loops1.cairo create mode 100644 solutions/loops/loops2.cairo create mode 100644 solutions/modules/modules1.cairo create mode 100644 solutions/modules/modules2.cairo create mode 100644 solutions/modules/readme.md create mode 100644 solutions/move_semantics/README.md create mode 100644 solutions/move_semantics/move_semantics1.cairo create mode 100644 solutions/move_semantics/move_semantics2.cairo create mode 100644 solutions/move_semantics/move_semantics3.cairo create mode 100644 solutions/move_semantics/move_semantics4.cairo create mode 100644 solutions/move_semantics/move_semantics5.cairo create mode 100644 solutions/move_semantics/move_semantics6.cairo create mode 100644 solutions/operations/README.md create mode 100644 solutions/operations/operations1.cairo create mode 100644 solutions/operations/operations2.cairo create mode 100644 solutions/options/README.md create mode 100644 solutions/options/options1.cairo create mode 100644 solutions/options/options2.cairo create mode 100644 solutions/options/options3.cairo create mode 100644 solutions/primitive_types/README.md create mode 100644 solutions/primitive_types/primitive_types1.cairo create mode 100644 solutions/primitive_types/primitive_types2.cairo create mode 100644 solutions/primitive_types/primitive_types3.cairo create mode 100644 solutions/primitive_types/primitive_types4.cairo create mode 100644 solutions/quizs/quizs1.cairo create mode 100644 solutions/structs/README.md create mode 100644 solutions/structs/structs1.cairo create mode 100644 solutions/structs/structs2.cairo create mode 100644 solutions/structs/structs3.cairo create mode 100644 solutions/traits/README.md create mode 100644 solutions/traits/traits1.cairo create mode 100644 solutions/traits/traits2.cairo create mode 100644 solutions/traits/traits3.cairo create mode 100644 solutions/variables/README.md create mode 100644 solutions/variables/variables1.cairo create mode 100644 solutions/variables/variables2.cairo create mode 100644 solutions/variables/variables3.cairo create mode 100644 solutions/variables/variables4.cairo create mode 100644 solutions/variables/variables5.cairo create mode 100644 solutions/variables/variables6.cairo diff --git a/exercises/dict/dict1.cairo b/exercises/dict/dict1.cairo index 6e5a9f5df..c426ddc94 100644 --- a/exercises/dict/dict1.cairo +++ b/exercises/dict/dict1.cairo @@ -7,6 +7,7 @@ // Make me compile and pass the test! // I AM NOT DONE +use core::dict::Felt252Dict; fn create_dictionary() -> Felt252Dict { let mut dict: Felt252Dict = Default::default(); diff --git a/exercises/dict/dict2.cairo b/exercises/dict/dict2.cairo index fe51655c8..a3b984611 100644 --- a/exercises/dict/dict2.cairo +++ b/exercises/dict/dict2.cairo @@ -4,6 +4,8 @@ // I AM NOT DONE +use core::dict::Felt252Dict; + fn multiply_element_by_10(ref dict: Felt252Dict, n: usize) { //TODO : make a function that multiplies the elements stored at the indexes 0 to n of a dictionary by 10 diff --git a/exercises/dict/dict3.cairo b/exercises/dict/dict3.cairo index 5f32ed874..ea1b2731a 100644 --- a/exercises/dict/dict3.cairo +++ b/exercises/dict/dict3.cairo @@ -6,6 +6,7 @@ // Make me compile and pass the test! // I AM NOT DONE +use core::dict::Felt252Dict; #[derive(Destruct)] struct Team { diff --git a/exercises/modules/modules1.cairo b/exercises/modules/modules1.cairo index b9b8db835..6774a701f 100644 --- a/exercises/modules/modules1.cairo +++ b/exercises/modules/modules1.cairo @@ -4,8 +4,8 @@ // I AM NOT DONE -mod restaurant { - fn take_order() -> felt252 { +pub mod restaurant { + pub fn take_order() -> felt252 { 'order_taken' } } diff --git a/exercises/modules/modules2.cairo b/exercises/modules/modules2.cairo index 6ea8d4a09..fa1be7eb6 100644 --- a/exercises/modules/modules2.cairo +++ b/exercises/modules/modules2.cairo @@ -3,31 +3,31 @@ const YEAR: u16 = 2050; -mod order { +pub mod order { #[derive(Copy, Drop)] - struct Order { - name: felt252, - year: u16, - made_by_phone: bool, - made_by_email: bool, - item: felt252, + pub struct Order { + pub name: felt252, + pub year: u16, + pub made_by_phone: bool, + pub made_by_email: bool, + pub item: felt252, } - fn new_order(name: felt252, made_by_phone: bool, item: felt252) -> Order { + pub fn new_order(name: felt252, made_by_phone: bool, item: felt252) -> Order { Order { name, year: YEAR, made_by_phone, made_by_email: !made_by_phone, item, } } } -mod order_utils { - fn dummy_phoned_order(name: felt252) -> Order { +pub mod order_utils { + pub fn dummy_phoned_order(name: felt252) -> Order { new_order(name, true, 'item_a') } - fn dummy_emailed_order(name: felt252) -> Order { + pub fn dummy_emailed_order(name: felt252) -> Order { new_order(name, false, 'item_a') } - fn order_fees(order: Order) -> felt252 { + pub fn order_fees(order: Order) -> felt252 { if order.made_by_phone { return 500; } diff --git a/exercises/move_semantics/move_semantics1.cairo b/exercises/move_semantics/move_semantics1.cairo index 6dae0a294..4961483d7 100644 --- a/exercises/move_semantics/move_semantics1.cairo +++ b/exercises/move_semantics/move_semantics1.cairo @@ -1,19 +1,17 @@ // I AM NOT DONE - fn main() { let arr0 = array![]; - let arr1 = fill_arr(arr0); + let mut arr1 = fill_arr(arr0); - // This is just a print statement for arrays. - println!("{:?}", arr1.clone()); + println!("arr1: {:?}", arr1); //TODO fix the error here without modifying this line. arr1.append(88); - println!("{:?}", arr1); + println!("arr1: {:?}", arr1); } fn fill_arr(arr: Array) -> Array { diff --git a/exercises/move_semantics/move_semantics2.cairo b/exercises/move_semantics/move_semantics2.cairo index 8a43a3d5f..882f9b17d 100644 --- a/exercises/move_semantics/move_semantics2.cairo +++ b/exercises/move_semantics/move_semantics2.cairo @@ -8,7 +8,11 @@ fn main() { let mut _arr1 = fill_arr(arr0); // Do not change the following line! - println!("{:?}", arr0); + print_arr(arr0); +} + +fn print_arr(arr: Array) { + println!("arr: {:?}", arr); } // Do not change the following line! diff --git a/exercises/move_semantics/move_semantics3.cairo b/exercises/move_semantics/move_semantics3.cairo index b03df8440..1ae2aa768 100644 --- a/exercises/move_semantics/move_semantics3.cairo +++ b/exercises/move_semantics/move_semantics3.cairo @@ -8,11 +8,11 @@ fn main() { let mut arr1 = fill_arr(arr0); - println!("{:?}", arr1.clone()); + println!("arr1: {:?}", arr1); arr1.append(88); - println!("{:?}", arr1.clone()); + println!("arr1: {:?}", arr1); } fn fill_arr(arr: Array) -> Array { diff --git a/exercises/move_semantics/move_semantics4.cairo b/exercises/move_semantics/move_semantics4.cairo index 87a4e348a..a84c9f8bd 100644 --- a/exercises/move_semantics/move_semantics4.cairo +++ b/exercises/move_semantics/move_semantics4.cairo @@ -9,11 +9,11 @@ fn main() { let mut arr1 = fill_arr(arr0); - println!("{:?}", arr1.clone()); + println!("arr1: {:?}", arr1); arr1.append(88); - println!("{:?}", arr1.clone()); + println!("arr1: {:?}", arr1); } // `fill_arr()` should no longer take `arr: Array` as argument diff --git a/exercises/options/options3.cairo b/exercises/options/options3.cairo index 6b099127e..adb90db9e 100644 --- a/exercises/options/options3.cairo +++ b/exercises/options/options3.cairo @@ -9,35 +9,18 @@ struct Student { } -fn display_grades(student: @Student, index: usize) { - // don't mind these lines! They are required when - // running recursive functions. - match gas::withdraw_gas() { - Option::Some(_) => {}, - Option::None => { - let mut data = ArrayTrait::new(); - data.append('Out of gas'); - panic(data); - }, +fn display_grades(student: @Student) { + let mut msg = ArrayTrait::new(); + msg.append(*student.name); + msg.append('\'s grades:'); + println!("{:?}", msg); + + for course in student.courses.span() { + // TODO: Modify the following lines so that if there is a grade for the course, it is printed. + // Otherwise, print "No grade". + // + println!("grade is {}", course.unwrap()); } - - if index == 0 { - let mut msg = ArrayTrait::new(); - msg.append(*student.name); - msg.append('\'s grades:'); - debug::print(msg); - } - if index >= student.courses.len() { - return (); - } - - let course = *student.courses.at(index); - - // TODO: Modify the following lines so that if there is a grade for the course, it is printed. - // Otherwise, print "No grade". - // - println!("grade is {}", course.unwrap()); - display_grades(student, index + 1); } @@ -51,7 +34,7 @@ fn test_all_defined() { Option::Some('A'), ]; let mut student = Student { name: 'Alice', courses: courses }; - display_grades(@student, 0); + display_grades(@student); } @@ -66,5 +49,5 @@ fn test_some_empty() { Option::None, ]; let mut student = Student { name: 'Bob', courses: courses }; - display_grades(@student, 0); + display_grades(@student); } diff --git a/exercises/primitive_types/primitive_types2.cairo b/exercises/primitive_types/primitive_types2.cairo index 9472d3ed9..d1315598d 100644 --- a/exercises/primitive_types/primitive_types2.cairo +++ b/exercises/primitive_types/primitive_types2.cairo @@ -73,7 +73,9 @@ impl PartialOrdFelt of PartialOrd { } #[inline(always)] fn lt(lhs: felt252, rhs: felt252) -> bool { - integer::u256_from_felt252(lhs) < integer::u256_from_felt252(rhs) + let lhs_u256: u256 = lhs.into(); + let rhs_u256: u256 = rhs.into(); + lhs_u256 < rhs_u256 } #[inline(always)] fn gt(lhs: felt252, rhs: felt252) -> bool { diff --git a/exercises/starknet/components/starknet6.cairo b/exercises/starknet/components/starknet6.cairo index d7dc3e20b..1e3f3607a 100644 --- a/exercises/starknet/components/starknet6.cairo +++ b/exercises/starknet/components/starknet6.cairo @@ -12,12 +12,12 @@ trait IOwnable { fn set_owner(ref self: TContractState, new_owner: ContractAddress); } -mod OwnableComponent { +pub mod OwnableComponent { use starknet::ContractAddress; use super::IOwnable; #[storage] - struct Storage { + pub struct Storage { owner: ContractAddress, } @@ -35,7 +35,7 @@ mod OwnableComponent { } #[starknet::contract] -mod OwnableCounter { +pub mod OwnableCounter { use starknet::ContractAddress; use super::OwnableComponent; @@ -51,7 +51,7 @@ mod OwnableCounter { OwnableEvent: OwnableComponent::Event, } #[storage] - struct Storage { + pub struct Storage { counter: u128, #[substorage(v0)] ownable: OwnableComponent::Storage, @@ -60,6 +60,7 @@ mod OwnableCounter { #[cfg(test)] mod tests { + use crate::IOwnableDispatcherTrait; use snforge_std::{declare, ContractClassTrait, DeclareResultTrait}; use starknet::{contract_address_const, ContractAddress}; use super::IOwnableDispatcher; diff --git a/runner-crate/Scarb.toml b/runner-crate/Scarb.toml index 4b848bfd9..5df48ba2a 100644 --- a/runner-crate/Scarb.toml +++ b/runner-crate/Scarb.toml @@ -3,7 +3,13 @@ name = "runner_crate" version = "0.1.0" edition = "2024_07" +[scripts] +test = "snforge test" + +[tool.scarb] +allow-prebuilt-plugins = ["snforge_std"] +# Core Starknet dependencies [dependencies] starknet = "2.11.4" @@ -11,11 +17,4 @@ starknet = "2.11.4" snforge_std = "0.44.0" assert_macros = "2.11.4" -[[target.starknet-contract]] -sierra = true - -[scripts] -test = "snforge test" - -[tool.scarb] -allow-prebuilt-plugins = ["snforge_std"] +# Starknet contract compilation target \ No newline at end of file diff --git a/solutions/arrays/README.md b/solutions/arrays/README.md new file mode 100644 index 000000000..3b1afc118 --- /dev/null +++ b/solutions/arrays/README.md @@ -0,0 +1,12 @@ +# Arrays + +Arrays are defined in the Cairo core library. They are a dynamically sized collection of elements of the same type. You can create and use array methods by importing the `array::ArrayTrait` trait. +An important thing to note is that arrays are append-only. This means that you can only add elements to the end of an array. +You cannot remove elements from an array, or modify the elements in an array. +This has to do with the fact that once a memory slot is written to, it cannot be overwritten, but only read from it. + +## Further information + +- [Arrays](https://book.cairo-lang.org/ch03-01-arrays.html) +- [Core library](https://github.com/starkware-libs/cairo/blob/main/corelib/src/array.cairo) +- [Cairo memory model](https://medium.com/nethermind-eth/cairo-fundamentals-stacked-up-against-evm-and-solidity-1d8d4e12b2c3#2c01) diff --git a/solutions/arrays/arrays1.cairo b/solutions/arrays/arrays1.cairo new file mode 100644 index 000000000..35bea9429 --- /dev/null +++ b/solutions/arrays/arrays1.cairo @@ -0,0 +1,21 @@ +// Your task is to create an `Array` which holds three elements of type `felt252`. +// The first element should be 0. +// Make me compile and pass the test! + +fn create_array() -> Array { + let mut a = ArrayTrait::new(); + a.append(0); + a.append(1); + a.append(2); + a +} + + +// Don't change anything in the test +#[cfg(test)] +#[test] +fn test_array_len() { + let mut a = create_array(); + assert(a.len() == 3, 'Array length is not 3'); + assert(a.pop_front().unwrap() == 0, 'First element is not 0'); +} diff --git a/solutions/arrays/arrays2.cairo b/solutions/arrays/arrays2.cairo new file mode 100644 index 000000000..6909708ff --- /dev/null +++ b/solutions/arrays/arrays2.cairo @@ -0,0 +1,31 @@ +// Your task is to make the test pass without modifying the `create_array` function. +// Make me compile and pass the test! + + + +// Don't modify this function +fn create_array() -> Array { + let mut a = ArrayTrait::new(); + a.append(42); + a +} + +fn remove_element_from_array(ref a: Array) { + let _ = a.pop_front(); +} + +#[cfg(test)] +#[test] +fn test_arrays2() { + let mut a = create_array(); + assert(a.len() == 1, 'Array should have one element'); + assert(*a.at(0) == 42, 'First element should be 42'); +} + +#[cfg(test)] +#[test] +fn test_arrays2_empty() { + let mut a = create_array(); + remove_element_from_array(ref a); + assert(a.len() == 0, 'Array length is not 0'); +} diff --git a/solutions/arrays/arrays3.cairo b/solutions/arrays/arrays3.cairo new file mode 100644 index 000000000..d9a0953ad --- /dev/null +++ b/solutions/arrays/arrays3.cairo @@ -0,0 +1,19 @@ +// Make me compile and pass the test! + + +fn create_array() -> Array { + let mut a = ArrayTrait::new(); // something to change here... + a.append(0); + a.append(1); + a.append(2); + a.pop_front().unwrap(); + a +} + + +#[cfg(test)] +#[test] +fn test_arrays3() { + let mut a = create_array(); + let _ = a.get(2); +} diff --git a/solutions/dict/README.md b/solutions/dict/README.md new file mode 100644 index 000000000..1acef05f2 --- /dev/null +++ b/solutions/dict/README.md @@ -0,0 +1,6 @@ +# Dicts +The Felt252Dict maps a felt252 to a value of the specified type. + +## Further information + +- [Dictionaries](https://book.cairo-lang.org/ch03-02-dictionaries.html) diff --git a/solutions/dict/dict1.cairo b/solutions/dict/dict1.cairo new file mode 100644 index 000000000..7ddd9d380 --- /dev/null +++ b/solutions/dict/dict1.cairo @@ -0,0 +1,31 @@ +// The Felt252Dict maps a felt252 to a value of the specified type. +// In this exercise, you will map a `felt252` key to a value of type `u32`. + +// Your task is to create a `Felt252Dict` containing three elements of type `u32`. +// The first element should map the key 'A' to the value 1, the second key 'B' to the value 2 +// and the third should map 'bob' to the value 3. +// Make me compile and pass the test! + +use core::dict::Felt252Dict; + +fn create_dictionary() -> Felt252Dict { + let mut dict: Felt252Dict = Default::default(); + // Insert the required key-value pairs + dict.insert('A', 1); + dict.insert('B', 2); + dict.insert('bob', 3); + + dict + +} + + +// Don't change anything in the test +#[cfg(test)] +#[test] +fn test_dict() { + let mut dict = create_dictionary(); + assert(dict.get('A') == 1, 'First element is not 1'); + assert(dict.get('B') == 2, 'Second element is not 2'); + assert(dict.get('bob') == 3, 'Third element is not 3'); +} diff --git a/solutions/dict/dict2.cairo b/solutions/dict/dict2.cairo new file mode 100644 index 000000000..64f7dba97 --- /dev/null +++ b/solutions/dict/dict2.cairo @@ -0,0 +1,45 @@ +// Dictionaries can be used to simulate dynamic array : the value they store can be accessed and modified. +// Your task is to create a function that multiplies the elements stored at the indexes 0 to n of a dictionary by 10 +// Make me compile and pass the test! + +use core::dict::Felt252Dict; + +fn multiply_element_by_10(ref dict: Felt252Dict, n: usize) { + //TODO : make a function that multiplies the elements stored at the indexes 0 to n of a dictionary by 10 + for i in 0..n { + let current_value = dict.get(i.into()); + dict.insert(i.into(), current_value * 10); + } +} + +// Don't change anything in the test +#[cfg(test)] +#[test] +fn test_3() { + let mut dict: Felt252Dict = Default::default(); + dict.insert(0, 1); + dict.insert(1, 2); + dict.insert(2, 3); + + multiply_element_by_10(ref dict, 3); + + assert(dict.get(0) == 10, 'First element is not 10'); + assert(dict.get(1) == 20, 'Second element is not 20'); + assert(dict.get(2) == 30, 'Third element is not 30'); +} + +#[cfg(test)] +#[test] +fn test_4() { + let mut dict: Felt252Dict = Default::default(); + dict.insert(0, 1); + dict.insert(1, 2); + dict.insert(2, 5); + dict.insert(3, 10); + + multiply_element_by_10(ref dict, 4); + + assert(dict.get(2) == 50, 'First element is not 50'); + assert(dict.get(3) == 100, 'First element is not 100'); + +} diff --git a/solutions/dict/dict3.cairo b/solutions/dict/dict3.cairo new file mode 100644 index 000000000..14b6866a4 --- /dev/null +++ b/solutions/dict/dict3.cairo @@ -0,0 +1,65 @@ +// Custom data structure using dicts +// Using Felt252Dict in structs allow us to simulate mutable data structures +// In this exercise we have a struct Team where a Felt252Dict maps the name of a player to its level and keeps track of +// the number of player. +// Using the methods set and get from the Felt252DictTrait, implement the required functions to interact with the team +// Make me compile and pass the test! + +use core::dict::Felt252Dict; + +#[derive(Destruct)] +struct Team { + level: Felt252Dict, + players_count: usize +} + +#[generate_trait] +impl TeamImpl of TeamTrait { + fn new() -> Team { + Team { + level: Default::default(), + players_count: 0 + } + } + + fn get_level(ref self: Team, name: felt252) -> usize { + self.level.get(name) + } + + fn add_player(ref self: Team, name: felt252, level: usize) -> () { + self.level.insert(name, level); + self.players_count += 1; + } + + fn level_up(ref self: Team, name: felt252) { + let current_level = self.level.get(name); + self.level.insert(name, current_level + 1); + } + + fn players_count(self: @Team) -> usize { + *self.players_count + } +} + + +#[cfg(test)] +#[test] +fn test_add_player() { + let mut team = TeamTrait::new(); + team.add_player('bob', 10); + team.add_player('alice', 20); + + assert(team.players_count == 2, 'Wrong number of player'); + assert(team.get_level('bob') == 10, 'Wrong level'); + assert(team.get_level('alice') == 20, 'Wrong level'); +} + +#[cfg(test)] +#[test] +fn test_level_up() { + let mut team = TeamTrait::new(); + team.add_player('bobby', 10); + team.level_up('bobby'); + + assert(team.level.get('bobby') == 11, 'Wrong level'); +} diff --git a/solutions/enums/README.md b/solutions/enums/README.md new file mode 100644 index 000000000..432717483 --- /dev/null +++ b/solutions/enums/README.md @@ -0,0 +1,9 @@ +# Enums + +Cairo allows you to define types called "enums" which enumerate possible values. +Enums are a feature in many languages, but their capabilities differ in each language. Cairo’s enums are most similar to Rust and algebraic data types in functional languages. +Useful in combination with enums is Cairo's "pattern matching" facility, which makes it easy to run different code for different values of an enumeration. + +## Further information + +- [Enums](https://book.cairo-lang.org/ch06-01-enums.html) diff --git a/solutions/enums/enums1.cairo b/solutions/enums/enums1.cairo new file mode 100644 index 000000000..3b55734c2 --- /dev/null +++ b/solutions/enums/enums1.cairo @@ -0,0 +1,29 @@ +use core::fmt::{Display, Formatter, Error}; + +#[derive(Drop)] +enum Message { + Quit, + Echo, + Move, + ChangeColor, +} + +fn main() { // don't change any of the lines inside main + println!("{}", Message::Quit); + println!("{}", Message::Echo); + println!("{}", Message::Move); + println!("{}", Message::ChangeColor); +} + +impl MessageDisplay of Display { + fn fmt(self: @Message, ref f: Formatter) -> Result<(), Error> { + let str: ByteArray = match self { + Message::Quit => format!("Quit"), + Message::Echo => format!("Echo"), + Message::Move => format!("Move"), + Message::ChangeColor => format!("ChangeColor"), + }; + f.buffer.append(@str); + Result::Ok(()) + } +} diff --git a/solutions/enums/enums2.cairo b/solutions/enums/enums2.cairo new file mode 100644 index 000000000..eab90bb89 --- /dev/null +++ b/solutions/enums/enums2.cairo @@ -0,0 +1,60 @@ + +use core::fmt::{Display, Formatter, Error}; + +#[derive(Copy, Drop)] +enum Message { + Quit, + Echo: felt252, + Move: (u32, u32), + ChangeColor: (u8, u8, u8), +} + + +fn main() { // don't change any of the lines inside main + let mut messages: Array = ArrayTrait::new(); + + //don't change any of the next 4 lines + messages.append(Message::Quit); + messages.append(Message::Echo('hello world')); + messages.append(Message::Move((10, 30))); + messages.append(Message::ChangeColor((0, 255, 255))); + + print_messages_recursive(messages, 0) +} + +// Utility function to print messages. Don't modify these. + +trait MessageTrait { + fn call(self: T); +} + +impl MessageImpl of MessageTrait { + fn call(self: Message) { + println!("{}", self); + } +} + +fn print_messages_recursive(messages: Array, index: u32) { + if index >= messages.len() { + return (); + } + let message = *messages.at(index); + message.call(); + print_messages_recursive(messages, index + 1) +} + + +impl MessageDisplay of Display { + fn fmt(self: @Message, ref f: Formatter) -> Result<(), Error> { + println!("___MESSAGE BEGINS___"); + let str: ByteArray = match self { + Message::Quit => format!("Quit"), + Message::Echo(msg) => format!("{}", msg), + Message::Move((a, b)) => { format!("{} {}", a, b) }, + Message::ChangeColor((red, green, blue)) => { format!("{} {} {}", red, green, blue) }, + }; + f.buffer.append(@str); + println!("___MESSAGE ENDS___"); + Result::Ok(()) + } +} diff --git a/solutions/enums/enums3.cairo b/solutions/enums/enums3.cairo new file mode 100644 index 000000000..0e3377047 --- /dev/null +++ b/solutions/enums/enums3.cairo @@ -0,0 +1,78 @@ +// Address all the TODOs to make the tests pass! + + + +#[derive(Drop, Copy)] +enum Message { + Quit, + Echo: felt252, + Move: Point, + ChangeColor: (u8, u8, u8), +} + +#[derive(Drop, Copy)] +struct Point { + x: u8, + y: u8, +} + +#[derive(Drop, Copy)] +struct State { + color: (u8, u8, u8), + position: Point, + quit: bool, +} + +trait StateTrait { + fn change_color(ref self: State, new_color: (u8, u8, u8)); + fn quit(ref self: State); + fn echo(ref self: State, s: felt252); + fn move_position(ref self: State, p: Point); + fn process(ref self: State, message: Message); +} +impl StateImpl of StateTrait { + fn change_color(ref self: State, new_color: (u8, u8, u8)) { + let State { color: _, position, quit } = self; + self = State { color: new_color, position: position, quit: quit }; + } + fn quit(ref self: State) { + let State { color, position, quit: _ } = self; + self = State { color: color, position: position, quit: true }; + } + + fn echo(ref self: State, s: felt252) { + println!("{}", s); + } + + fn move_position(ref self: State, p: Point) { + let State { color, position: _, quit } = self; + self = State { color: color, position: p, quit: quit }; + } + + fn process( + ref self: State, message: Message, + ) { + match message { + Message::Quit => self.quit(), + Message::Echo(s) => self.echo(s), + Message::Move(p) => self.move_position(p), + Message::ChangeColor(c) => self.change_color(c), + } + } +} + + +#[cfg(test)] +#[test] +fn test_match_message_call() { + let mut state = State { quit: false, position: Point { x: 0, y: 0 }, color: (0, 0, 0) }; + state.process(Message::ChangeColor((255, 0, 255))); + state.process(Message::Echo('hello world')); + state.process(Message::Move(Point { x: 10, y: 15 })); + state.process(Message::Quit); + + assert(state.color == (255, 0, 255), 'wrong color'); + assert(state.position.x == 10, 'wrong x position'); + assert(state.position.y == 15, 'wrong y position'); + assert(state.quit, 'quit should be true'); +} diff --git a/solutions/functions/README.md b/solutions/functions/README.md new file mode 100644 index 000000000..56d82af41 --- /dev/null +++ b/solutions/functions/README.md @@ -0,0 +1,5 @@ +# Functions + +Here, you'll learn how to write and use functions in Cairo. + +[Functions](https://book.cairo-lang.org/ch02-03-functions.html) diff --git a/solutions/functions/functions1.cairo b/solutions/functions/functions1.cairo new file mode 100644 index 000000000..2186f4fbb --- /dev/null +++ b/solutions/functions/functions1.cairo @@ -0,0 +1,9 @@ + + +fn main() { + call_me(); +} + +fn call_me() { + println!("Hello, world!"); +} diff --git a/solutions/functions/functions2.cairo b/solutions/functions/functions2.cairo new file mode 100644 index 000000000..e6b511914 --- /dev/null +++ b/solutions/functions/functions2.cairo @@ -0,0 +1,9 @@ + + +fn main() { + call_me(3); +} + +fn call_me(num: u32) { + println!("num is {}", num); +} diff --git a/solutions/functions/functions3.cairo b/solutions/functions/functions3.cairo new file mode 100644 index 000000000..c6548638a --- /dev/null +++ b/solutions/functions/functions3.cairo @@ -0,0 +1,9 @@ + + +fn main() { + call_me(5); +} + +fn call_me(num: u64) { + println!("num is {}", num); +} diff --git a/solutions/functions/functions4.cairo b/solutions/functions/functions4.cairo new file mode 100644 index 000000000..4bc52ca15 --- /dev/null +++ b/solutions/functions/functions4.cairo @@ -0,0 +1,24 @@ +// This store is having a sale where if the price is an even number, you get +// 10 Cairobucks off, but if it's an odd number, it's 3 Cairobucks off. +// (Don't worry about the function bodies themselves, we're only interested +// in the signatures for now. If anything, this is a good way to peek ahead +// to future exercises!) + + + +fn main() { + let original_price = 51; + println!("sale_price is {}", sale_price(original_price)); +} + +fn sale_price(price: u32) -> u32 { + if is_even(price) { + price - 10 + } else { + price - 3 + } +} + +fn is_even(num: u32) -> bool { + num % 2 == 0 +} diff --git a/solutions/if/README.md b/solutions/if/README.md new file mode 100644 index 000000000..6fb5bead0 --- /dev/null +++ b/solutions/if/README.md @@ -0,0 +1,7 @@ +# If + +`if`, the most basic (but still surprisingly versatile!) type of control flow, is what you'll learn here. + +## Further information + +- [If expressions](https://book.cairo-lang.org/ch02-05-control-flow.html#if-expressions) diff --git a/solutions/if/if1.cairo b/solutions/if/if1.cairo new file mode 100644 index 000000000..064e567e5 --- /dev/null +++ b/solutions/if/if1.cairo @@ -0,0 +1,25 @@ +// Make the tests pass. + +fn bigger(a: usize, b: usize) -> usize { + if a > b { + a + } else { + b + } +} + +// Don't mind this for now :) +#[cfg(test)] +mod tests { + use super::bigger; + + #[test] + fn ten_is_bigger_than_eight() { + assert(10 == bigger(10, 8), '10 bigger than 8'); + } + + #[test] + fn fortytwo_is_bigger_than_thirtytwo() { + assert(42 == bigger(32, 42), '42 bigger than 32'); + } +} diff --git a/solutions/if/if2.cairo b/solutions/if/if2.cairo new file mode 100644 index 000000000..f7495f5b6 --- /dev/null +++ b/solutions/if/if2.cairo @@ -0,0 +1,40 @@ +// Step 1: Make me compile! +// Step 2: Get the bar_for_fuzz and default_to_baz tests passing! + + + +fn foo_if_fizz(fizzish: felt252) -> felt252 { + // Complete this function using if, else if and/or else blocks. + // If fizzish is, + // 'fizz', return 'foo' + // 'fuzz', return 'bar' + // anything else, return 'baz' + if fizzish == 'fizz' { + 'foo' + } else if fizzish == 'fuzz' { + 'bar' + } else { + 'baz' + } +} + +// No test changes needed! +#[cfg(test)] +mod tests { + use super::foo_if_fizz; + + #[test] + fn foo_for_fizz() { + assert(foo_if_fizz('fizz') == 'foo', 'fizz returns foo') + } + + #[test] + fn bar_for_fuzz() { + assert(foo_if_fizz('fuzz') == 'bar', 'fuzz returns bar'); + } + + #[test] + fn default_to_baz() { + assert(foo_if_fizz('literally anything') == 'baz', 'anything else returns baz'); + } +} diff --git a/solutions/intro/intro1.cairo b/solutions/intro/intro1.cairo new file mode 100644 index 000000000..866976ce8 --- /dev/null +++ b/solutions/intro/intro1.cairo @@ -0,0 +1,5 @@ +// This exercise doesn't do anything yet but it still compiles! Cairo file getting run +// needs to have a `main` function. So this file is a valid Cairo file. +// Other exercises will require you to write Cairo code to make the exercise file compile. + +fn main() {} diff --git a/solutions/intro/intro2.cairo b/solutions/intro/intro2.cairo new file mode 100644 index 000000000..a4553a38c --- /dev/null +++ b/solutions/intro/intro2.cairo @@ -0,0 +1,5 @@ + +// This exercise won't compile... Can you make it compile? + +fn main() { +} diff --git a/solutions/loops/README.md b/solutions/loops/README.md new file mode 100644 index 000000000..b56b72090 --- /dev/null +++ b/solutions/loops/README.md @@ -0,0 +1,5 @@ +# Loops + +Cairo provides a simple syntax to execute a block of code multiple times. This is done using the `loop` keyword, which is followed by a block of code. The block of code is executed repeatedly until a `break` statement is encountered. + +- [Loops](https://book.cairo-lang.org/ch02-05-control-flow.html#repetition-with-loops) diff --git a/solutions/loops/loops1.cairo b/solutions/loops/loops1.cairo new file mode 100644 index 000000000..723be5650 --- /dev/null +++ b/solutions/loops/loops1.cairo @@ -0,0 +1,16 @@ + + + +#[cfg(test)] +#[test] +fn test_loop() { + let mut counter = 0; + //TODO make the test pass without changing any existing line + loop { + counter += 1; + if counter == 10 { + break (); + } + }; + assert(counter == 10, 'counter should be 10') +} diff --git a/solutions/loops/loops2.cairo b/solutions/loops/loops2.cairo new file mode 100644 index 000000000..0e44be8c3 --- /dev/null +++ b/solutions/loops/loops2.cairo @@ -0,0 +1,18 @@ + + + + +#[cfg(test)] +#[test] +fn test_loop() { + let mut counter = 0; + + let result = loop { + if counter == 5 { + break counter; + } + counter += 1; + }; + + assert(result == 5, 'result should be 5'); +} diff --git a/solutions/modules/modules1.cairo b/solutions/modules/modules1.cairo new file mode 100644 index 000000000..4a8fbe89d --- /dev/null +++ b/solutions/modules/modules1.cairo @@ -0,0 +1,29 @@ +// We are writing an app for a restaurant, +// but take_order functions are not being called correctly. +// Can you fix this? + +pub mod restaurant { + pub fn take_order() -> felt252 { + 'order_taken' + } +} + +#[cfg(test)] +#[test] +fn test_mod_fn() { + // Fix this line to call take_order function from module + let order_result = restaurant::take_order(); + + assert(order_result == 'order_taken', 'Order not taken'); +} + +#[cfg(test)] +mod tests { + #[test] + fn test_super_fn() { + // Fix this line to call take_order function + let order_result = super::restaurant::take_order(); + + assert(order_result == 'order_taken', 'Order not taken'); + } +} diff --git a/solutions/modules/modules2.cairo b/solutions/modules/modules2.cairo new file mode 100644 index 000000000..7bc32398b --- /dev/null +++ b/solutions/modules/modules2.cairo @@ -0,0 +1,51 @@ + +// These modules have some issues, can you fix them? + +const YEAR: u16 = 2050; + +pub mod order { + #[derive(Copy, Drop)] + pub struct Order { + pub name: felt252, + pub year: u16, + pub made_by_phone: bool, + pub made_by_email: bool, + pub item: felt252, + } + + pub fn new_order(name: felt252, made_by_phone: bool, item: felt252) -> Order { + Order { name, year: super::YEAR, made_by_phone, made_by_email: !made_by_phone, item, } + } +} + +pub mod order_utils { + use super::order::{new_order, Order}; + + pub fn dummy_phoned_order(name: felt252) -> Order { + new_order(name, true, 'item_a') + } + + pub fn dummy_emailed_order(name: felt252) -> Order { + new_order(name, false, 'item_a') + } + + pub fn order_fees(order: Order) -> felt252 { + if order.made_by_phone { + return 500; + } + + 200 + } +} + +#[cfg(test)] +#[test] +fn test_array() { + let order1 = order_utils::dummy_phoned_order('John Doe'); + let fees1 = order_utils::order_fees(order1); + assert(fees1 == 500, 'Order fee should be 500'); + + let order2 = order_utils::dummy_emailed_order('Jane Doe'); + let fees2 = order_utils::order_fees(order2); + assert(fees2 == 200, 'Order fee should be 200'); +} diff --git a/solutions/modules/readme.md b/solutions/modules/readme.md new file mode 100644 index 000000000..7a37eb251 --- /dev/null +++ b/solutions/modules/readme.md @@ -0,0 +1,76 @@ +# Modules + +Modules allow creating individual scopes and organise your code better. Read about [modules in cairo book](https://book.cairo-lang.org/ch07-02-defining-modules-to-control-scope.html). + +Here's some code to show modules at play, + +## Declaring modules + +Modules can be declared in two ways, + +| Code | Description | +| --------------- | ---------------------------- | +| `mod filename;` | Module from a filename.cairo | +| `mod { ... }` | Inline module code in braces | + +In the exercises we'll use inline modules, but the behaviour is identical. + +### `lib.cairo` + +```rust +// Module from a file +mod restaurant; + +fn main() { + // ... +} +``` + +### `restaurant.cairo` + +```rust +fn add_to_waitlist() {} +fn seat_at_table() {} + +// Inline modules +mod serving { + fn take_order() {} + fn serve_order() {} +} + +mod checkout { + fn get_bill() {} + fn collect_payment() {} +} +``` + +## Using stuff in modules + +| Keyword | Description | Example | +| ------- | ------------------- | ------------------------- | +| `super` | Access parent scope | `super::my_module::my_fn` | +| `use` | Create shortcuts | `use my_module::my_fn` | + +### `lib.cairo` + +```rust +// ... +use restaurant::seat_at_table; // Creates shortcut to seat_at_table +use restaurant::serving::serve_order; // Another shortcut +use restaurant::checkout; // Shortcut to a module + + +fn main() { + restaurant::add_to_waitlist(); + seat_at_table(); // Shortcut thanks to use + + restaurant::serving::take_order(); + serve_order(); // Via shortcut +} + +mod cutomer_checkout { + fn start() { + super::checkout::collect_payment(); + } +} +``` diff --git a/solutions/move_semantics/README.md b/solutions/move_semantics/README.md new file mode 100644 index 000000000..0232b26c8 --- /dev/null +++ b/solutions/move_semantics/README.md @@ -0,0 +1,8 @@ +# Move Semantics + +## Further information + +For this section, reading the Cairo book references is especially important. + +- [Ownership](https://book.cairo-lang.org/ch04-00-understanding-ownership.html) +- [Reference and borrowing](https://book.cairo-lang.org/ch04-02-references-and-snapshots.html) diff --git a/solutions/move_semantics/move_semantics1.cairo b/solutions/move_semantics/move_semantics1.cairo new file mode 100644 index 000000000..b227a99fb --- /dev/null +++ b/solutions/move_semantics/move_semantics1.cairo @@ -0,0 +1,23 @@ +fn main() { + let mut arr0 = ArrayTrait::new(); + + let mut arr1 = fill_arr(arr0); + + println!("arr1: {:?}", arr1); + + //TODO fix the error here without modifying this line. + arr1.append(88); + + println!("arr1: {:?}", arr1); + +} + +fn fill_arr(arr: Array) -> Array { + let mut arr = arr; + + arr.append(22); + arr.append(44); + arr.append(66); + + arr +} diff --git a/solutions/move_semantics/move_semantics2.cairo b/solutions/move_semantics/move_semantics2.cairo new file mode 100644 index 000000000..5e4e0eae3 --- /dev/null +++ b/solutions/move_semantics/move_semantics2.cairo @@ -0,0 +1,26 @@ +// Make me compile without changing the indicated lines + + +fn main() { + let arr0 = ArrayTrait::new(); + + let mut arr1 = fill_arr(arr0); + + // Do not change the following line! + print_arr(arr0); +} + +fn print_arr(arr: Array) { + println!("arr: {:?}", arr); +} + +// Do not change the following line! +fn fill_arr(arr: Array) -> Array { + let mut arr = arr; + + arr.append(22); + arr.append(44); + arr.append(66); + + arr +} diff --git a/solutions/move_semantics/move_semantics3.cairo b/solutions/move_semantics/move_semantics3.cairo new file mode 100644 index 000000000..6daf66374 --- /dev/null +++ b/solutions/move_semantics/move_semantics3.cairo @@ -0,0 +1,22 @@ +// Make me compile without adding new lines-- just changing existing lines! +// (no lines with multiple semicolons necessary!) + +fn main() { + let arr0 = ArrayTrait::new(); + + let mut arr1 = fill_arr(arr0); + + println!("arr1: {:?}", arr1); + + arr1.append(88); + + println!("arr1: {:?}", arr1); +} + +fn fill_arr(mut arr: Array) -> Array { + arr.append(22); + arr.append(44); + arr.append(66); + + arr +} diff --git a/solutions/move_semantics/move_semantics4.cairo b/solutions/move_semantics/move_semantics4.cairo new file mode 100644 index 000000000..5e435113b --- /dev/null +++ b/solutions/move_semantics/move_semantics4.cairo @@ -0,0 +1,24 @@ +// Refactor this code so that instead of passing `arr0` into the `fill_arr` function, +// the Array gets created in the function itself and passed back to the main +// function. + +fn main() { + let mut arr1 = fill_arr(); + + println!("arr1: {:?}", arr1); + + arr1.append(88); + + println!("arr1: {:?}", arr1); +} + +// `fill_arr()` should no longer take `arr: Array` as argument +fn fill_arr() -> Array { + let mut arr = ArrayTrait::::new(); + + arr.append(22); + arr.append(44); + arr.append(66); + + arr +} diff --git a/solutions/move_semantics/move_semantics5.cairo b/solutions/move_semantics/move_semantics5.cairo new file mode 100644 index 000000000..865233d2e --- /dev/null +++ b/solutions/move_semantics/move_semantics5.cairo @@ -0,0 +1,22 @@ +// Make me compile only by reordering the lines in `main()`, but without +// adding, changing or removing any of them. + + + +#[cfg(test)] +#[test] +fn main() { + let mut a = ArrayTrait::new(); + pass_by_ref(ref a); + pass_by_snapshot(@a); + let mut b = pass_by_value(a); + pass_by_ref(ref b); +} + +fn pass_by_value(mut arr: Array) -> Array { + arr +} + +fn pass_by_ref(ref arr: Array) {} + +fn pass_by_snapshot(x: @Array) {} diff --git a/solutions/move_semantics/move_semantics6.cairo b/solutions/move_semantics/move_semantics6.cairo new file mode 100644 index 000000000..71576f1cb --- /dev/null +++ b/solutions/move_semantics/move_semantics6.cairo @@ -0,0 +1,26 @@ +// You can't change anything except adding or removing references. + +#[derive(Drop)] +struct Number { + value: u32, +} + +fn main() { + let mut number = Number { value: 1111111 }; + + get_value(@number); + + set_value(number); +} + +// Should not take ownership and not modify the variable passed. +fn get_value(number: @Number) -> u32 { + *number.value +} + +// Should take ownership +fn set_value(mut number: Number) { + let value = 2222222; + number = Number { value }; + println!("Number is: {}", number.value); +} diff --git a/solutions/operations/README.md b/solutions/operations/README.md new file mode 100644 index 000000000..bdf17d163 --- /dev/null +++ b/solutions/operations/README.md @@ -0,0 +1,6 @@ +# Felt operations + +A field element - felt, is a native type in Cairo. Learn more about it in the [Cairo book](https://book.cairo-lang.org/ch02-02-data-types.html#felt-type) to learn more about it + +Cairo1 has native integer types which support more operators then felts, like %, / +Take a look [here](https://book.cairo-lang.org/ch02-02-data-types.html#integer-types) for more details diff --git a/solutions/operations/operations1.cairo b/solutions/operations/operations1.cairo new file mode 100644 index 000000000..222e45368 --- /dev/null +++ b/solutions/operations/operations1.cairo @@ -0,0 +1,26 @@ +// Integer types implement basic comparison and arithmetic operators. +// Felt252 operations should be avoided where possible, as they could have unwanted behavior. + + + + +fn poly(x: usize, y: usize) -> usize { + // Return the solution of x^3 + y - 2 + let res = x * x * x + y - 2; + res // Do not change +} + + +// Do not change the test function +#[cfg(test)] +#[test] +fn test_poly() { + let res = poly(5, 3); + assert(res == 126, 'Error message'); + assert(res < 300, 'res < 300'); + assert(res <= 300, 'res <= 300'); + assert(res > 20, 'res > 20'); + assert(res >= 2, 'res >= 2'); + assert(res != 27, 'res != 27'); + assert(res % 2 == 0, 'res %2 != 0'); +} diff --git a/solutions/operations/operations2.cairo b/solutions/operations/operations2.cairo new file mode 100644 index 000000000..fc7b2b448 --- /dev/null +++ b/solutions/operations/operations2.cairo @@ -0,0 +1,58 @@ +// Remember last time you calculated division in Cairo0? +// Now Cairo1 has native integer types e.g. u8, u32, ...u256, usize which support more operators than felts +// And always watch out for overflows e.g in the last test +// Let try to use them + +fn modulus(x: u8, y: u8) -> u8 { + // calculate the modulus of x and y + x % y +} + +fn floor_division(x: usize, y: usize) -> usize { + // calculate the floor_division of x and y + x / y +} + +fn multiplication(x: u64, y: u64) -> u64 { + // calculate the multiplication of x and y + x * y +} + + +// Do not change the tests +#[cfg(test)] +#[test] +fn test_modulus() { + let res = modulus(16, 2); + assert(res == 0, 'Error message'); + + let res = modulus(17, 3); + assert(res == 2, 'Error message'); +} + +#[cfg(test)] +#[test] +fn test_floor_division() { + let res = floor_division(160, 2); + assert(res == 80, 'Error message'); + + let res = floor_division(21, 4); + assert(res == 5, 'Error message'); +} + +#[cfg(test)] +#[test] +fn test_mul() { + let res = multiplication(16, 2); + assert(res == 32, 'Error message'); + + let res = multiplication(21, 4); + assert(res == 84, 'Error message'); +} + +#[cfg(test)] +#[test] +#[should_panic] +fn test_u64_mul_overflow_1() { + let _res = multiplication(0x100000000, 0x100000000); +} diff --git a/solutions/options/README.md b/solutions/options/README.md new file mode 100644 index 000000000..577c18851 --- /dev/null +++ b/solutions/options/README.md @@ -0,0 +1,13 @@ +# Options + +Type **`Option`** represents an optional value: every **`Option`** is either **`Some`** and contains a value, or *`None`**, and does not. +**`Option`** types are very common in Cairo code, as they have a number of uses: + +- Initial values +- Return values for functions that are not defined over their entire input range (partial functions) +- Return value for otherwise reporting simple errors, where **`None`** is returned on error +- Optional struct fields +- Optional function arguments +## Further Information + +- [Option Implementation](https://book.cairo-lang.org/ch06-01-enums.html#the-option-enum-and-its-advantages) diff --git a/solutions/options/options1.cairo b/solutions/options/options1.cairo new file mode 100644 index 000000000..d1d56e459 --- /dev/null +++ b/solutions/options/options1.cairo @@ -0,0 +1,37 @@ + + + + +// This function returns how much icecream there is left in the fridge. +// If it's before 10PM, there's 5 pieces left. At 10PM, someone eats them +// all, so there'll be no more left :( +fn maybe_icecream( + time_of_day: usize +) -> Option { + if time_of_day > 23 { + None + } else if time_of_day < 22 { + Some(5) + } else { + Some(0) + } +} + + +#[cfg(test)] +#[test] +fn check_icecream() { + assert(maybe_icecream(9).unwrap() == 5, 'err_1'); + assert(maybe_icecream(10).unwrap() == 5, 'err_2'); + assert(maybe_icecream(23).unwrap() == 0, 'err_3'); + assert(maybe_icecream(22).unwrap() == 0, 'err_4'); + assert(maybe_icecream(25).is_none(), 'err_5'); +} + +#[cfg(test)] +#[test] +fn raw_value() { + // TODO: Fix this test. How do you get at the value contained in the Option? + let icecreams = maybe_icecream(12); + assert(icecreams.unwrap() == 5, 'err_6'); +} diff --git a/solutions/options/options2.cairo b/solutions/options/options2.cairo new file mode 100644 index 000000000..1a38b94a2 --- /dev/null +++ b/solutions/options/options2.cairo @@ -0,0 +1,25 @@ + + + + +#[cfg(test)] +#[test] +fn test_options() { + let target = 'starklings'; + let optional_some = Option::Some(target); + let optional_none: Option = Option::None; + simple_option(optional_some); + simple_option(optional_none); +} + +fn simple_option(optional_target: Option) { + // TODO: use the `is_some` and `is_none` methods to check if `optional_target` contains a value. + // Place the assertion and the print statement below in the correct blocks. + if optional_target.is_some() { + assert!(optional_target.unwrap() == 'starklings'); + println!(" option is empty ! "); + } else { + assert!(optional_target.is_none()); + println!(" option is empty ! "); + } +} diff --git a/solutions/options/options3.cairo b/solutions/options/options3.cairo new file mode 100644 index 000000000..272f56029 --- /dev/null +++ b/solutions/options/options3.cairo @@ -0,0 +1,52 @@ + + +#[derive(Drop)] +struct Student { + name: felt252, + courses: Array>, +} + + +fn display_grades(student: @Student) { + let mut msg = ArrayTrait::new(); + msg.append(*student.name); + msg.append('\'s grades:'); + println!("{:?}", msg); + + for course in student.courses.span() { + if course.is_some() { + println!("grade is {}", course.unwrap()); + } else { + println!("No grade"); + } + } +} + + +#[cfg(test)] +#[test] +fn test_all_defined() { + let courses = array![ + Option::Some('A'), + Option::Some('B'), + Option::Some('C'), + Option::Some('A'), + ]; + let mut student = Student { name: 'Alice', courses: courses }; + display_grades(@student); +} + + +#[cfg(test)] +#[test] +fn test_some_empty() { + let courses = array![ + Option::Some('A'), + Option::None, + Option::Some('B'), + Option::Some('C'), + Option::None, + ]; + let mut student = Student { name: 'Bob', courses: courses }; + display_grades(@student); +} diff --git a/solutions/primitive_types/README.md b/solutions/primitive_types/README.md new file mode 100644 index 000000000..422541097 --- /dev/null +++ b/solutions/primitive_types/README.md @@ -0,0 +1,6 @@ +# Primitive Types + +Cairo has a couple of basic types that are directly implemented into the +compiler. In this section, we'll go through the most important ones. + +[Data Types](https://book.cairo-lang.org/ch02-02-data-types.html) diff --git a/solutions/primitive_types/primitive_types1.cairo b/solutions/primitive_types/primitive_types1.cairo new file mode 100644 index 000000000..a6dc082a5 --- /dev/null +++ b/solutions/primitive_types/primitive_types1.cairo @@ -0,0 +1,18 @@ +// Fill in the rest of the line that has code missing! +// No hints, there's no tricks, just get used to typing these :) + + + +fn main() { + // Booleans (`bool`) + + let is_morning = true; + if is_morning { + println!("Good morning!"); + } + + let is_evening = false; + if is_evening { + println!("Good evening!"); + } +} diff --git a/solutions/primitive_types/primitive_types2.cairo b/solutions/primitive_types/primitive_types2.cairo new file mode 100644 index 000000000..b9f372895 --- /dev/null +++ b/solutions/primitive_types/primitive_types2.cairo @@ -0,0 +1,82 @@ +// Fill in the rest of the line that has code missing! +// No hints, there's no tricks, just get used to typing these :) + +fn main() { + // A short string is a string whose length is at most 31 characters, and therefore can fit into a single field element. + // Short strings are actually felts, they are not a real string. + // Note the _single_ quotes that are used with short strings. + + let mut my_first_initial = 'C'; + if is_alphabetic( + ref my_first_initial + ) { + println!(" Alphabetical !"); + } else if is_numeric( + ref my_first_initial + ) { + println!(" Numerical !"); + } else { + println!(" Neither alphabetic nor numeric!"); + } + + let mut your_character = 'A'; // Finish this line like the example! What's your favorite short string? + // Try a letter, try a number, try a special character, try a short string! + if is_alphabetic( + ref your_character + ) { + println!(" Alphabetical !"); + } else if is_numeric( + ref your_character + ) { + println!(" Numerical!"); + } else { + println!(" Neither alphabetic nor numeric!"); + } +} + +fn is_alphabetic(ref char: felt252) -> bool { + if char >= 'a' { + if char <= 'z' { + return true; + } + } + if char >= 'A' { + if char <= 'Z' { + return true; + } + } + false +} + +fn is_numeric(ref char: felt252) -> bool { + if char >= '0' { + if char <= '9' { + return true; + } + } + false +} + +// Note: the following code is not part of the challenge, it's just here to make the code above work. +// Direct felt252 comparisons have been removed from the core library, so we need to implement them ourselves. +// There will probably be a string / short string type in the future +impl PartialOrdFelt of PartialOrd { + #[inline(always)] + fn le(lhs: felt252, rhs: felt252) -> bool { + !(rhs < lhs) + } + #[inline(always)] + fn ge(lhs: felt252, rhs: felt252) -> bool { + !(lhs < rhs) + } + #[inline(always)] + fn lt(lhs: felt252, rhs: felt252) -> bool { + let lhs_u256: u256 = lhs.into(); + let rhs_u256: u256 = rhs.into(); + lhs_u256 < rhs_u256 + } + #[inline(always)] + fn gt(lhs: felt252, rhs: felt252) -> bool { + rhs < lhs + } +} diff --git a/solutions/primitive_types/primitive_types3.cairo b/solutions/primitive_types/primitive_types3.cairo new file mode 100644 index 000000000..bc15bcc9f --- /dev/null +++ b/solutions/primitive_types/primitive_types3.cairo @@ -0,0 +1,10 @@ +// Destructure the `cat` tuple to call print on each member. + + + +fn main() { + let cat = ('Furry McFurson', 3); + let (name, age) = cat; + println!("name is {}", name); + println!("age is {}", age); +} diff --git a/solutions/primitive_types/primitive_types4.cairo b/solutions/primitive_types/primitive_types4.cairo new file mode 100644 index 000000000..2072e6e9c --- /dev/null +++ b/solutions/primitive_types/primitive_types4.cairo @@ -0,0 +1,48 @@ +// Modify the integer types to make the tests pass. +// Learn how to convert between integer types, and felts. + + +fn sum_u8s(x: u8, y: u8) -> u8 { + x + y +} + +//TODO modify the types of this function to prevent an overflow when summing big values +fn sum_big_numbers(x: u16, y: u16) -> u16 { + x + y +} + +fn convert_to_felt(x: u8) -> felt252 { + x.into() +} + +fn convert_felt_to_u8(x: felt252) -> u8 { + x.try_into().unwrap() +} + +#[cfg(test)] +#[test] +fn test_sum_u8s() { + assert(sum_u8s(1, 2_u8) == 3_u8, 'Something went wrong'); +} + +#[cfg(test)] +#[test] +fn test_sum_big_numbers() { + //TODO modify this test to use the correct integer types. + // Don't modify the values, just the types. + // See how using the _u8 suffix on the numbers lets us specify the type? + // Try to do the same thing with other integer types. + assert(sum_big_numbers(255_u16, 255_u16) == 510_u16, 'Something went wrong'); +} + +#[cfg(test)] +#[test] +fn test_convert_to_felt() { + assert(convert_to_felt(1_u8) == 1, 'Type conversion went wrong'); +} + +#[cfg(test)] +#[test] +fn test_convert_to_u8() { + assert(convert_felt_to_u8(1) == 1_u8, 'Type conversion went wrong'); +} diff --git a/solutions/quizs/quizs1.cairo b/solutions/quizs/quizs1.cairo new file mode 100644 index 000000000..27c0000de --- /dev/null +++ b/solutions/quizs/quizs1.cairo @@ -0,0 +1,28 @@ +// Mary is buying apples. The price of an apple is calculated as follows: +// - An apple costs 3 cairobucks. +// - If Mary buys more than 40 apples, each apple only costs 2 cairobuck! +// Write a function that calculates the price of an order of apples given +// the quantity bought. No hints this time! + +fn calculate_price_of_apples(quantity: u32) -> u32 { + if quantity > 40 { + quantity * 2 + } else { + quantity * 3 + } +} + +// Do not change the tests! +#[cfg(test)] +#[test] +fn verify_test() { + let price1 = calculate_price_of_apples(35); + let price2 = calculate_price_of_apples(40); + let price3 = calculate_price_of_apples(41); + let price4 = calculate_price_of_apples(65); + + assert(105 == price1, 'Incorrect price'); + assert(120 == price2, 'Incorrect price'); + assert(82 == price3, 'Incorrect price'); + assert(130 == price4, 'Incorrect price'); +} diff --git a/solutions/starknet/components/starknet6.cairo b/solutions/starknet/components/starknet6.cairo index d7dc3e20b..72a7bb4de 100644 --- a/solutions/starknet/components/starknet6.cairo +++ b/solutions/starknet/components/starknet6.cairo @@ -2,8 +2,6 @@ // This should add OwnableComponent containing functionality which any contracts can include. // But something is fishy here as this component is not working, can you find the error and make the tests pass? -// I AM NOT DONE - use starknet::ContractAddress; #[starknet::interface] @@ -12,12 +10,14 @@ trait IOwnable { fn set_owner(ref self: TContractState, new_owner: ContractAddress); } -mod OwnableComponent { +#[starknet::component] +pub mod OwnableComponent { use starknet::ContractAddress; + use starknet::storage::*; use super::IOwnable; #[storage] - struct Storage { + pub struct Storage { owner: ContractAddress, } @@ -35,7 +35,7 @@ mod OwnableComponent { } #[starknet::contract] -mod OwnableCounter { +pub mod OwnableCounter { use starknet::ContractAddress; use super::OwnableComponent; @@ -51,7 +51,7 @@ mod OwnableCounter { OwnableEvent: OwnableComponent::Event, } #[storage] - struct Storage { + pub struct Storage { counter: u128, #[substorage(v0)] ownable: OwnableComponent::Storage, @@ -60,6 +60,7 @@ mod OwnableCounter { #[cfg(test)] mod tests { + use crate::IOwnableDispatcherTrait; use snforge_std::{declare, ContractClassTrait, DeclareResultTrait}; use starknet::{contract_address_const, ContractAddress}; use super::IOwnableDispatcher; diff --git a/solutions/starknet/interoperability/starknet5.cairo b/solutions/starknet/interoperability/starknet5.cairo index 43ca13f09..5babb270a 100644 --- a/solutions/starknet/interoperability/starknet5.cairo +++ b/solutions/starknet/interoperability/starknet5.cairo @@ -1,6 +1,6 @@ // Address all the TODOs to make the tests pass! -// I AM NOT DONE + #[starknet::interface] trait IContractA { diff --git a/solutions/structs/README.md b/solutions/structs/README.md new file mode 100644 index 000000000..72807bd8e --- /dev/null +++ b/solutions/structs/README.md @@ -0,0 +1,17 @@ +# Structs + +Cairo has a single type of struct representing named collections of related data stored in fields. +They are declared like so: + +```rust +struct Rectangle { + width: felt252, + height: felt252, +} +``` + +## Further information + +- [Defining and instantiating Structs](https://book.cairo-lang.org/ch05-01-defining-and-instantiating-structs.html) +- [An example program using structs](https://book.cairo-lang.org/ch05-02-an-example-program-using-structs.html) +- [The Method syntax](https://book.cairo-lang.org/ch05-03-method-syntax.html) diff --git a/solutions/structs/structs1.cairo b/solutions/structs/structs1.cairo new file mode 100644 index 000000000..7d9c98b3f --- /dev/null +++ b/solutions/structs/structs1.cairo @@ -0,0 +1,21 @@ +// Address all the TODOs to make the tests pass! + +#[derive(Copy, Drop)] +struct ColorStruct { + red: u8, + green: u8, + blue: u8, +} + + +#[cfg(test)] +#[test] +fn classic_c_structs() { + // TODO: Instantiate a classic color struct! + // Green color neeeds to have green set to 255 and, red and blue, set to 0 + let green = ColorStruct { red: 0, green: 255, blue: 0 }; + + assert(green.red == 0, 0); + assert(green.green == 255, 0); + assert(green.blue == 0, 0); +} diff --git a/solutions/structs/structs2.cairo b/solutions/structs/structs2.cairo new file mode 100644 index 000000000..79531fe93 --- /dev/null +++ b/solutions/structs/structs2.cairo @@ -0,0 +1,39 @@ +// Address all the TODOs to make the tests pass! + +#[derive(Copy, Drop)] +struct Order { + name: felt252, + year: felt252, + made_by_phone: bool, + made_by_mobile: bool, + made_by_email: bool, + item_number: felt252, + count: felt252, +} + +fn create_order_template() -> Order { + Order { + name: 'Bob', + year: 2019, + made_by_phone: false, + made_by_mobile: false, + made_by_email: true, + item_number: 123, + count: 0 + } +} +#[cfg(test)] +#[test] +fn test_your_order() { + let order_template = create_order_template(); + // TODO: Destructure your order into multiple variables to make the assertions pass! + let Order { name, year, made_by_phone, made_by_mobile, made_by_email, item_number, count } = order_template; + + assert(name == 'Bob', 'Wrong name'); + assert(year == order_template.year, 'Wrong year'); + assert(made_by_phone == order_template.made_by_phone, 'Wrong phone'); + assert(made_by_mobile == order_template.made_by_mobile, 'Wrong mobile'); + assert(made_by_email == order_template.made_by_email, 'Wrong email'); + assert(item_number == order_template.item_number, 'Wrong item number'); + assert(count == 0, 'Wrong count'); +} diff --git a/solutions/structs/structs3.cairo b/solutions/structs/structs3.cairo new file mode 100644 index 000000000..d491bba33 --- /dev/null +++ b/solutions/structs/structs3.cairo @@ -0,0 +1,78 @@ +// Structs contain data, but can also have logic. In this exercise we have +// defined the Package struct and we want to test some logic attached to it. +// Make the code compile and the tests pass! + +#[derive(Copy, Drop)] +struct Package { + sender_country: felt252, + recipient_country: felt252, + weight_in_grams: usize, +} + +trait PackageTrait { + fn new(sender_country: felt252, recipient_country: felt252, weight_in_grams: usize) -> Package; + fn is_international(ref self: Package) -> bool; + fn get_fees(ref self: Package, cents_per_gram: usize) -> usize; +} +impl PackageImpl of PackageTrait { + fn new(sender_country: felt252, recipient_country: felt252, weight_in_grams: usize) -> Package { + if weight_in_grams <= 0{ + let mut data = ArrayTrait::new(); + data.append('x'); + panic(data); + } + Package { sender_country, recipient_country, weight_in_grams, } + } + + fn is_international(ref self: Package) -> bool { + self.sender_country != self.recipient_country + } + + fn get_fees(ref self: Package, cents_per_gram: usize) -> usize { + self.weight_in_grams * cents_per_gram + } +} + +#[cfg(test)] +#[test] +#[should_panic] +fn fail_creating_weightless_package() { + let sender_country = 'Spain'; + let recipient_country = 'Austria'; + PackageTrait::new(sender_country, recipient_country, 0); +} + +#[cfg(test)] +#[test] +fn create_international_package() { + let sender_country = 'Spain'; + let recipient_country = 'Russia'; + + let mut package = PackageTrait::new(sender_country, recipient_country, 1200); + + assert(package.is_international() == true, 'Not international'); +} + +#[cfg(test)] +#[test] +fn create_local_package() { + let sender_country = 'Canada'; + let recipient_country = sender_country; + + let mut package = PackageTrait::new(sender_country, recipient_country, 1200); + + assert(package.is_international() == false, 'International'); +} + +#[cfg(test)] +#[test] +fn calculate_transport_fees() { + let sender_country = 'Spain'; + let recipient_country = 'Spain'; + + let cents_per_gram = 3; + + let mut package = PackageTrait::new(sender_country, recipient_country, 1500); + + assert(package.get_fees(cents_per_gram) == 4500, 'Wrong fees'); +} diff --git a/solutions/traits/README.md b/solutions/traits/README.md new file mode 100644 index 000000000..bb5d37cd8 --- /dev/null +++ b/solutions/traits/README.md @@ -0,0 +1,11 @@ +# Traits + +A trait is a collection of methods. + +Data types can implement traits. To do so, the methods making up the trait are defined for the data type. For example, the `felt` data type implements the `Into` trait. This allows a user to write `1.into()` to convert a felt into a u256. + +In this way, traits are somewhat similar to Java interfaces and C++ abstract classes. + +Because traits indicate shared behavior between data types, they are useful when writing generics. + +- [Traits & Impls](https://book.cairo-lang.org/ch08-02-traits-in-cairo.html) diff --git a/solutions/traits/traits1.cairo b/solutions/traits/traits1.cairo new file mode 100644 index 000000000..3a37e335f --- /dev/null +++ b/solutions/traits/traits1.cairo @@ -0,0 +1,41 @@ +// Time to implement some traits! + +// Your task is to implement the trait +// `AnimalTrait` for the type `Animal` +// + +// Fill in the impl block to make the code work. + + + +#[derive(Copy, Drop)] +struct Animal { + noise: felt252 +} + +trait AnimalTrait { + fn new(noise: felt252) -> Animal; + fn make_noise(self: Animal) -> felt252; +} + +impl AnimalImpl of AnimalTrait { // TODO: implement the trait AnimalTrait for Animal + fn new(noise: felt252) -> Animal { + Animal { noise } + } + + fn make_noise(self: Animal) -> felt252 { + self.noise + } +} + +#[cfg(test)] +#[test] +fn test_traits1() { + // TODO make the test pass by creating two instances of Animal + // and calling make_noise on them + let cat = AnimalTrait::new('meow'); + let cow = AnimalTrait::new('moo'); + + assert(cat.make_noise() == 'meow', 'Wrong noise'); + assert(cow.make_noise() == 'moo', 'Wrong noise'); +} diff --git a/solutions/traits/traits2.cairo b/solutions/traits/traits2.cairo new file mode 100644 index 000000000..240c536f8 --- /dev/null +++ b/solutions/traits/traits2.cairo @@ -0,0 +1,59 @@ + +// The previous exercise did not make the distinction +// between different types of animals, but this one does. +// The trait `AnimalTrait` has two functions: +// `new` and `make_noise`. +// `new` should return a new instance of the type +// implementing the trait. +// `make_noise` should return the noise the animal makes. +// The types `Cat` and `Cow` are already defined for you. +// You need to implement the trait `AnimalTrait` for them. + +// No hints for this one! + + + +#[derive(Copy, Drop)] +struct Cat { + noise: felt252, +} + +#[derive(Copy, Drop)] +struct Cow { + noise: felt252, +} + +trait AnimalTrait { + fn new() -> T; + fn make_noise(self: T) -> felt252; +} + +impl CatImpl of AnimalTrait { + fn new() -> Cat { + Cat { noise: 'meow' } + } + + fn make_noise(self: Cat) -> felt252 { + self.noise + } +} + +impl CowImpl of AnimalTrait { + fn new() -> Cow { + Cow { noise: 'moo' } + } + + fn make_noise(self: Cow) -> felt252 { + self.noise + } +} + +#[cfg(test)] +#[test] +fn test_traits2() { + let kitty: Cat = AnimalTrait::new(); + assert(kitty.make_noise() == 'meow', 'Wrong noise'); + + let cow: Cow = AnimalTrait::new(); + assert(cow.make_noise() == 'moo', 'Wrong noise'); +} diff --git a/solutions/traits/traits3.cairo b/solutions/traits/traits3.cairo new file mode 100644 index 000000000..1468ca5b0 --- /dev/null +++ b/solutions/traits/traits3.cairo @@ -0,0 +1,83 @@ +// +// The previous exercise showed how to implement a trait for multiple types. +// This exercise shows how you can implement multiple traits for a single type. +// This is useful when you have types that share some common functionality, but +// also have some unique functionality. + + + +#[derive(Copy, Drop)] +struct Fish { + noise: felt252, + distance: u32, +} + +#[derive(Copy, Drop)] +struct Dog { + noise: felt252, + distance: u32, +} + +trait AnimalTrait { + fn new() -> T; + fn make_noise(self: T) -> felt252; + fn get_distance(self: T) -> u32; +} + +trait FishTrait { + fn swim(ref self: Fish) -> (); +} + +trait DogTrait { + fn walk(ref self: Dog) -> (); +} + +impl AnimalFishImpl of AnimalTrait { + fn new() -> Fish { + Fish { noise: 'blub', distance: 0 } + } + fn make_noise(self: Fish) -> felt252 { + self.noise + } + fn get_distance(self: Fish) -> u32 { + self.distance + } +} + +impl AnimalDogImpl of AnimalTrait { + fn new() -> Dog { + Dog { noise: 'woof', distance: 0 } + } + fn make_noise(self: Dog) -> felt252 { + self.noise + } + fn get_distance(self: Dog) -> u32 { + self.distance + } +} + +impl FishTraitImpl of FishTrait { + fn swim(ref self: Fish) { + self.distance += 1; + } +} + +impl DogTraitImpl of DogTrait { + fn walk(ref self: Dog) { + self.distance += 1; + } +} + +#[test] +fn test_traits3() { + // Don't modify this test! + let mut salmon: Fish = AnimalTrait::new(); + salmon.swim(); + assert(salmon.make_noise() == 'blub', 'Wrong noise'); + assert(salmon.get_distance() == 1, 'Wrong distance'); + + let mut dog: Dog = AnimalTrait::new(); + dog.walk(); + assert(dog.make_noise() == 'woof', 'Wrong noise'); + assert(dog.get_distance() == 1, 'Wrong distance'); +} diff --git a/solutions/variables/README.md b/solutions/variables/README.md new file mode 100644 index 000000000..97ae312e2 --- /dev/null +++ b/solutions/variables/README.md @@ -0,0 +1,13 @@ +# Variables + +In Cairo, variables are immutable by default. +When a variable is immutable, once a value is bound to a name, you can’t change that value. +You can make them mutable by adding mut in front of the variable name. + +It is however important to clarify the fact that even though the variable can be made mutable, Cairo works with an immutable memory model, meaning that changing the value of a variable will not change the value in memory but rather assign a new memory location to that variable. + +## Further information + +- [Memory model (from Cairo 0)](https://www.cairo-lang.org/docs/how_cairo_works/cairo_intro.html#memory-model) +- [Variables](https://book.cairo-lang.org/ch02-01-variables-and-mutability.html) +- [Integer types](https://book.cairo-lang.org/ch02-02-data-types.html#integer-types) diff --git a/solutions/variables/variables1.cairo b/solutions/variables/variables1.cairo new file mode 100644 index 000000000..7969352d7 --- /dev/null +++ b/solutions/variables/variables1.cairo @@ -0,0 +1,8 @@ +// Make me compile! + + + +fn main() { + let x = 5; + println!(" x is {}", x) +} diff --git a/solutions/variables/variables2.cairo b/solutions/variables/variables2.cairo new file mode 100644 index 000000000..c28b32293 --- /dev/null +++ b/solutions/variables/variables2.cairo @@ -0,0 +1,11 @@ + + + +fn main() { + let x = 10; + if x == 10 { + println!("x is ten! "); + } else { + println!("x is not ten! "); + } +} diff --git a/solutions/variables/variables3.cairo b/solutions/variables/variables3.cairo new file mode 100644 index 000000000..26b59f430 --- /dev/null +++ b/solutions/variables/variables3.cairo @@ -0,0 +1,7 @@ + + + +fn main() { + let x: felt252 = 0; + println!("x is {}", x); +} diff --git a/solutions/variables/variables4.cairo b/solutions/variables/variables4.cairo new file mode 100644 index 000000000..9c0b0c4c3 --- /dev/null +++ b/solutions/variables/variables4.cairo @@ -0,0 +1,8 @@ + + +fn main() { + let mut x = 3; + println!("x is {}", x); + x = 5; // don't change this line + println!("x is now {}", x); +} diff --git a/solutions/variables/variables5.cairo b/solutions/variables/variables5.cairo new file mode 100644 index 000000000..4ec671978 --- /dev/null +++ b/solutions/variables/variables5.cairo @@ -0,0 +1,8 @@ + + +fn main() { + let mut number = 1_u8; + println!("number is {}", number); + number = 3; // don't rename this variable + println!("number is {}", number); +} diff --git a/solutions/variables/variables6.cairo b/solutions/variables/variables6.cairo new file mode 100644 index 000000000..5e451a3ad --- /dev/null +++ b/solutions/variables/variables6.cairo @@ -0,0 +1,8 @@ + + +const NUMBER: felt252 = 3; +const SMALL_NUMBER: u8 = 3_u8; +fn main() { + println!("NUMBER is {}", NUMBER); + println!("SMALL_NUMBER is {}", SMALL_NUMBER); +} From 7eb6e21575fe9dc460695d6d6ed7f8601b69075d Mon Sep 17 00:00:00 2001 From: enitrat Date: Sun, 13 Jul 2025 16:39:34 +0100 Subject: [PATCH 05/12] remove unwanted files --- src/lib.cairo | 10 ---------- tests/lib.cairo | 8 -------- 2 files changed, 18 deletions(-) delete mode 100644 src/lib.cairo delete mode 100644 tests/lib.cairo diff --git a/src/lib.cairo b/src/lib.cairo deleted file mode 100644 index fd56defca..000000000 --- a/src/lib.cairo +++ /dev/null @@ -1,10 +0,0 @@ -mod exercises { - mod starknet { - mod components { - mod starknet6; - } - mod interoperability { - mod starknet5; - } - } -} diff --git a/tests/lib.cairo b/tests/lib.cairo deleted file mode 100644 index bc801c7de..000000000 --- a/tests/lib.cairo +++ /dev/null @@ -1,8 +0,0 @@ -mod starknet { - mod components { - mod test_starknet6; - } - mod interoperability { - mod test_starknet5; - } -} From 5679dbcec9ca2e706c857b63522db2d91315800d Mon Sep 17 00:00:00 2001 From: enitrat Date: Wed, 16 Jul 2025 18:23:33 +0100 Subject: [PATCH 06/12] refactor: use assert macros everywhere --- exercises/arrays/arrays1.cairo | 4 ++-- exercises/arrays/arrays2.cairo | 4 ++-- exercises/dict/dict1.cairo | 6 +++--- exercises/dict/dict2.cairo | 10 +++++----- exercises/dict/dict3.cairo | 8 ++++---- exercises/enums/enums3.cairo | 6 +++--- exercises/if/if2.cairo | 6 +++--- exercises/loops/loops1.cairo | 2 +- exercises/loops/loops2.cairo | 2 +- exercises/modules/modules1.cairo | 4 ++-- exercises/modules/modules2.cairo | 4 ++-- exercises/operations/operations1.cairo | 14 +++++++------- exercises/operations/operations2.cairo | 12 ++++++------ exercises/options/options1.cairo | 12 ++++++------ exercises/options/options2.cairo | 2 +- exercises/primitive_types/primitive_types4.cairo | 4 ++-- exercises/quizs/quizs1.cairo | 8 ++++---- exercises/starknet/basics/starknet1.cairo | 2 +- exercises/starknet/basics/starknet2.cairo | 2 +- exercises/starknet/basics/starknet3.cairo | 2 +- exercises/starknet/basics/starknet4.cairo | 10 +++++----- .../starknet/interoperability/starknet5.cairo | 6 +++--- exercises/structs/structs2.cairo | 14 +++++++------- exercises/structs/structs3.cairo | 6 +++--- exercises/traits/traits1.cairo | 4 ++-- exercises/traits/traits2.cairo | 4 ++-- exercises/traits/traits3.cairo | 8 ++++---- solutions/arrays/arrays1.cairo | 4 ++-- solutions/arrays/arrays2.cairo | 6 +++--- solutions/dict/dict1.cairo | 6 +++--- solutions/dict/dict2.cairo | 10 +++++----- solutions/dict/dict3.cairo | 8 ++++---- solutions/enums/enums3.cairo | 6 +++--- solutions/if/if2.cairo | 6 +++--- solutions/loops/loops1.cairo | 2 +- solutions/loops/loops2.cairo | 2 +- solutions/modules/modules1.cairo | 4 ++-- solutions/modules/modules2.cairo | 4 ++-- solutions/operations/operations1.cairo | 14 +++++++------- solutions/operations/operations2.cairo | 12 ++++++------ solutions/options/options1.cairo | 12 ++++++------ solutions/primitive_types/primitive_types4.cairo | 4 ++-- solutions/quizs/quizs1.cairo | 8 ++++---- solutions/starknet/basics/starknet1.cairo | 2 +- solutions/starknet/basics/starknet2.cairo | 2 +- solutions/starknet/basics/starknet3.cairo | 4 ++-- solutions/starknet/basics/starknet4.cairo | 14 +++++++------- .../starknet/interoperability/starknet5.cairo | 6 +++--- solutions/structs/structs2.cairo | 14 +++++++------- solutions/structs/structs3.cairo | 6 +++--- solutions/traits/traits1.cairo | 4 ++-- solutions/traits/traits2.cairo | 4 ++-- solutions/traits/traits3.cairo | 8 ++++---- 53 files changed, 169 insertions(+), 169 deletions(-) diff --git a/exercises/arrays/arrays1.cairo b/exercises/arrays/arrays1.cairo index 265213968..67ca61313 100644 --- a/exercises/arrays/arrays1.cairo +++ b/exercises/arrays/arrays1.cairo @@ -16,6 +16,6 @@ fn create_array() -> Array { #[test] fn test_array_len() { let mut a = create_array(); - assert(a.len() == 3, 'Array length is not 3'); - assert(a.pop_front().unwrap() == 0, 'First element is not 0'); + assert!(a.len() == 3, "Array length is not 3"); + assert!(a.pop_front().unwrap() == 0, "First element is not 0"); } diff --git a/exercises/arrays/arrays2.cairo b/exercises/arrays/arrays2.cairo index 57b625052..7c6f5219e 100644 --- a/exercises/arrays/arrays2.cairo +++ b/exercises/arrays/arrays2.cairo @@ -19,7 +19,7 @@ fn remove_element_from_array( #[test] fn test_arrays2() { let mut a = create_array(); - assert(*a.at(0) == 42, 'First element is not 42'); + assert!(*a.at(0) == 42, "First element is not 42"); } #[cfg(test)] @@ -27,5 +27,5 @@ fn test_arrays2() { fn test_arrays2_empty() { let mut a = create_array(); remove_element_from_array(ref a); - assert(a.len() == 0, 'Array length is not 0'); + assert!(a.len() == 0, "Array length is not 0"); } diff --git a/exercises/dict/dict1.cairo b/exercises/dict/dict1.cairo index c426ddc94..b5eaea28a 100644 --- a/exercises/dict/dict1.cairo +++ b/exercises/dict/dict1.cairo @@ -21,7 +21,7 @@ fn create_dictionary() -> Felt252Dict { #[test] fn test_dict() { let mut dict = create_dictionary(); - assert(dict.get('A') == 1, 'First element is not 1'); - assert(dict.get('B') == 2, 'Second element is not 2'); - assert(dict.get('bob') == 3, 'Third element is not 3'); + assert!(dict.get('A') == 1, "First element is not 1"); + assert!(dict.get('B') == 2, "Second element is not 2"); + assert!(dict.get('bob') == 3, "Third element is not 3"); } diff --git a/exercises/dict/dict2.cairo b/exercises/dict/dict2.cairo index a3b984611..aac1ff6c0 100644 --- a/exercises/dict/dict2.cairo +++ b/exercises/dict/dict2.cairo @@ -24,9 +24,9 @@ fn test_3() { multiply_element_by_10(ref dict, 3); - assert(dict.get(0) == 10, 'First element is not 10'); - assert(dict.get(1) == 20, 'Second element is not 20'); - assert(dict.get(2) == 30, 'Third element is not 30'); + assert!(dict.get(0) == 10, "First element is not 10"); + assert!(dict.get(1) == 20, "Second element is not 20"); + assert!(dict.get(2) == 30, "Third element is not 30"); } #[cfg(test)] @@ -40,7 +40,7 @@ fn test_4() { multiply_element_by_10(ref dict, 4); - assert(dict.get(2) == 50, 'First element is not 50'); - assert(dict.get(3) == 100, 'First element is not 100'); + assert!(dict.get(2) == 50, "First element is not 50"); + assert!(dict.get(3) == 100, "First element is not 100"); } diff --git a/exercises/dict/dict3.cairo b/exercises/dict/dict3.cairo index ea1b2731a..9b37809f8 100644 --- a/exercises/dict/dict3.cairo +++ b/exercises/dict/dict3.cairo @@ -45,9 +45,9 @@ fn test_add_player() { team.add_player('bob', 10); team.add_player('alice', 20); - assert(team.players_count == 2, 'Wrong number of player'); - assert(team.get_level('bob') == 10, 'Wrong level'); - assert(team.get_level('alice') == 20, 'Wrong level'); + assert!(team.players_count == 2, "Wrong number of player"); + assert!(team.get_level('bob') == 10, "Wrong level"); + assert!(team.get_level('alice') == 20, "Wrong level"); } #[cfg(test)] @@ -57,5 +57,5 @@ fn test_level_up() { team.add_player('bobby', 10); team.level_up('bobby'); - assert(team.level.get('bobby') == 11, 'Wrong level'); + assert!(team.level.get('bobby') == 11, "Wrong level"); } diff --git a/exercises/enums/enums3.cairo b/exercises/enums/enums3.cairo index fb4c759d7..9b3ee0615 100644 --- a/exercises/enums/enums3.cairo +++ b/exercises/enums/enums3.cairo @@ -62,7 +62,7 @@ fn test_match_message_call() { state.process(Message::Quit); assert(state.color == (255, 0, 255), 'wrong color'); - assert(state.position.x == 10, 'wrong x position'); - assert(state.position.y == 15, 'wrong y position'); - assert(state.quit == true, 'quit should be true'); + assert!(state.position.x == 10, "wrong x position"); + assert!(state.position.y == 15, "wrong y position"); + assert!(state.quit == true, "quit should be true"); } diff --git a/exercises/if/if2.cairo b/exercises/if/if2.cairo index c52903748..37f80133e 100644 --- a/exercises/if/if2.cairo +++ b/exercises/if/if2.cairo @@ -23,16 +23,16 @@ mod tests { #[test] fn foo_for_fizz() { - assert(foo_if_fizz('fizz') == 'foo', 'fizz returns foo') + assert!(foo_if_fizz('fizz') == 'foo', "fizz returns foo") } #[test] fn bar_for_fuzz() { - assert(foo_if_fizz('fuzz') == 'bar', 'fuzz returns bar'); + assert!(foo_if_fizz('fuzz') == 'bar', "fuzz returns bar"); } #[test] fn default_to_baz() { - assert(foo_if_fizz('literally anything') == 'baz', 'anything else returns baz'); + assert!(foo_if_fizz('literally anything') == 'baz', "anything else returns baz"); } } diff --git a/exercises/loops/loops1.cairo b/exercises/loops/loops1.cairo index 149bb4030..5b1f1f95b 100644 --- a/exercises/loops/loops1.cairo +++ b/exercises/loops/loops1.cairo @@ -10,5 +10,5 @@ fn test_loop() { break (); counter += 1; }; - assert(counter == 10, 'counter should be 10') + assert!(counter == 10, "counter should be 10") } diff --git a/exercises/loops/loops2.cairo b/exercises/loops/loops2.cairo index 020e7a4a3..0bf9b5c68 100644 --- a/exercises/loops/loops2.cairo +++ b/exercises/loops/loops2.cairo @@ -14,5 +14,5 @@ fn test_loop() { counter += 1; }; - assert(result == 5, 'result should be 5'); + assert!(result == 5, "result should be 5"); } diff --git a/exercises/modules/modules1.cairo b/exercises/modules/modules1.cairo index 6774a701f..be7dd34ee 100644 --- a/exercises/modules/modules1.cairo +++ b/exercises/modules/modules1.cairo @@ -16,7 +16,7 @@ fn test_mod_fn() { // Fix this line to call take_order function from module let order_result = take_order(); - assert(order_result == 'order_taken', 'Order not taken'); + assert!(order_result == 'order_taken', "Order not taken"); } #[cfg(test)] @@ -26,6 +26,6 @@ mod tests { // Fix this line to call take_order function let order_result = take_order(); - assert(order_result == 'order_taken', 'Order not taken'); + assert!(order_result == 'order_taken', "Order not taken"); } } diff --git a/exercises/modules/modules2.cairo b/exercises/modules/modules2.cairo index fa1be7eb6..2ad51f2e9 100644 --- a/exercises/modules/modules2.cairo +++ b/exercises/modules/modules2.cairo @@ -41,9 +41,9 @@ pub mod order_utils { fn test_array() { let order1 = order_utils::dummy_phoned_order('John Doe'); let fees1 = order_utils::order_fees(order1); - assert(fees1 == 500, 'Order fee should be 500'); + assert!(fees1 == 500, "Order fee should be 500"); let order2 = order_utils::dummy_emailed_order('Jane Doe'); let fees2 = order_utils::order_fees(order2); - assert(fees2 == 200, 'Order fee should be 200'); + assert!(fees2 == 200, "Order fee should be 200"); } diff --git a/exercises/operations/operations1.cairo b/exercises/operations/operations1.cairo index 0bd713fe2..ccd2026ce 100644 --- a/exercises/operations/operations1.cairo +++ b/exercises/operations/operations1.cairo @@ -16,11 +16,11 @@ fn poly(x: usize, y: usize) -> usize { #[test] fn test_poly() { let res = poly(5, 3); - assert(res == 126, 'Error message'); - assert(res < 300, 'res < 300'); - assert(res <= 300, 'res <= 300'); - assert(res > 20, 'res > 20'); - assert(res >= 2, 'res >= 2'); - assert(res != 27, 'res != 27'); - assert(res % 2 == 0, 'res %2 != 0'); + assert!(res == 126, "Error message"); + assert!(res < 300, "res < 300"); + assert!(res <= 300, "res <= 300"); + assert!(res > 20, "res > 20"); + assert!(res >= 2, "res >= 2"); + assert!(res != 27, "res != 27"); + assert!(res % 2 == 0, "res %2 != 0"); } diff --git a/exercises/operations/operations2.cairo b/exercises/operations/operations2.cairo index 075aa3eaf..8b147a4ce 100644 --- a/exercises/operations/operations2.cairo +++ b/exercises/operations/operations2.cairo @@ -29,30 +29,30 @@ fn multiplication(x: u64, y: u64) -> u64 { #[test] fn test_modulus() { let res = modulus(16, 2); - assert(res == 0, 'Error message'); + assert!(res == 0, "Error message"); let res = modulus(17, 3); - assert(res == 2, 'Error message'); + assert!(res == 2, "Error message"); } #[cfg(test)] #[test] fn test_floor_division() { let res = floor_division(160, 2); - assert(res == 80, 'Error message'); + assert!(res == 80, "Error message"); let res = floor_division(21, 4); - assert(res == 5, 'Error message'); + assert!(res == 5, "Error message"); } #[cfg(test)] #[test] fn test_mul() { let res = multiplication(16, 2); - assert(res == 32, 'Error message'); + assert!(res == 32, "Error message"); let res = multiplication(21, 4); - assert(res == 84, 'Error message'); + assert!(res == 84, "Error message"); } #[cfg(test)] diff --git a/exercises/options/options1.cairo b/exercises/options/options1.cairo index 1441deeed..3a5a0b86e 100644 --- a/exercises/options/options1.cairo +++ b/exercises/options/options1.cairo @@ -16,11 +16,11 @@ fn maybe_icecream( #[cfg(test)] #[test] fn check_icecream() { - assert(maybe_icecream(9).unwrap() == 5, 'err_1'); - assert(maybe_icecream(10).unwrap() == 5, 'err_2'); - assert(maybe_icecream(23).unwrap() == 0, 'err_3'); - assert(maybe_icecream(22).unwrap() == 0, 'err_4'); - assert(maybe_icecream(25).is_none(), 'err_5'); + assert!(maybe_icecream(9).unwrap() == 5, "err_1"); + assert!(maybe_icecream(10).unwrap() == 5, "err_2"); + assert!(maybe_icecream(23).unwrap() == 0, "err_3"); + assert!(maybe_icecream(22).unwrap() == 0, "err_4"); + assert!(maybe_icecream(25).is_none(), "err_5"); } #[cfg(test)] @@ -28,5 +28,5 @@ fn check_icecream() { fn raw_value() { // TODO: Fix this test. How do you get at the value contained in the Option? let icecreams = maybe_icecream(12); - assert(icecreams == 5, 'err_6'); + assert!(icecreams == 5, "err_6"); } diff --git a/exercises/options/options2.cairo b/exercises/options/options2.cairo index e172368f8..25d64d87a 100644 --- a/exercises/options/options2.cairo +++ b/exercises/options/options2.cairo @@ -15,6 +15,6 @@ fn test_options() { fn simple_option(optional_target: Option) { // TODO: use the `is_some` and `is_none` methods to check if `optional_target` contains a value. // Place the assertion and the print statement below in the correct blocks. - assert(optional_target.unwrap() == 'starklings', 'err1'); + assert!(optional_target.unwrap() == 'starklings', "err1"); println!(" option is empty ! "); } diff --git a/exercises/primitive_types/primitive_types4.cairo b/exercises/primitive_types/primitive_types4.cairo index da397ba95..3b10d7d58 100644 --- a/exercises/primitive_types/primitive_types4.cairo +++ b/exercises/primitive_types/primitive_types4.cairo @@ -37,11 +37,11 @@ fn test_sum_big_numbers() { #[cfg(test)] #[test] fn test_convert_to_felt() { - assert(convert_to_felt(1_u8) == 1, 'Type conversion went wrong'); + assert!(convert_to_felt(1_u8) == 1, "Type conversion went wrong"); } #[cfg(test)] #[test] fn test_convert_to_u8() { - assert(convert_felt_to_u8(1) == 1_u8, 'Type conversion went wrong'); + assert!(convert_felt_to_u8(1) == 1_u8, "Type conversion went wrong"); } diff --git a/exercises/quizs/quizs1.cairo b/exercises/quizs/quizs1.cairo index 118778b12..abe58e841 100644 --- a/exercises/quizs/quizs1.cairo +++ b/exercises/quizs/quizs1.cairo @@ -19,8 +19,8 @@ fn verify_test() { let price3 = calculate_price_of_apples(41); let price4 = calculate_price_of_apples(65); - assert(105 == price1, 'Incorrect price'); - assert(120 == price2, 'Incorrect price'); - assert(82 == price3, 'Incorrect price'); - assert(130 == price4, 'Incorrect price'); + assert!(105 == price1, "Incorrect price"); + assert!(120 == price2, "Incorrect price"); + assert!(82 == price3, "Incorrect price"); + assert!(130 == price4, "Incorrect price"); } diff --git a/exercises/starknet/basics/starknet1.cairo b/exercises/starknet/basics/starknet1.cairo index c538fe990..e4bd30c12 100644 --- a/exercises/starknet/basics/starknet1.cairo +++ b/exercises/starknet/basics/starknet1.cairo @@ -29,7 +29,7 @@ mod test { #[test] fn test_contract_view() { let dispatcher = deploy_contract(); - assert('Joe' == dispatcher.get_owner(), 'Joe should be the owner.'); + assert!('Joe' == dispatcher.get_owner(), "Joe should be the owner."); } fn deploy_contract() -> IJoesContractDispatcher { diff --git a/exercises/starknet/basics/starknet2.cairo b/exercises/starknet/basics/starknet2.cairo index f50266d29..006ade2a4 100644 --- a/exercises/starknet/basics/starknet2.cairo +++ b/exercises/starknet/basics/starknet2.cairo @@ -49,6 +49,6 @@ mod test { let (contract_address, _) = contract.deploy(@calldata).unwrap(); let dispatcher = IJillsContractDispatcher { contract_address }; let owner = dispatcher.get_owner(); - assert(owner == 'Jill'.try_into().unwrap(), 'Owner should be Jill'); + assert!(owner == 'Jill'.try_into().unwrap(), "Owner should be Jill"); } } diff --git a/exercises/starknet/basics/starknet3.cairo b/exercises/starknet/basics/starknet3.cairo index e12c6c3be..de3f3dea7 100644 --- a/exercises/starknet/basics/starknet3.cairo +++ b/exercises/starknet/basics/starknet3.cairo @@ -63,7 +63,7 @@ mod test { fn test_owner() { let owner: ContractAddress = 'Sensei'.try_into().unwrap(); let dispatcher = deploy_contract(); - assert(owner == dispatcher.get_contract_owner(), 'Mr. Sensei should be the owner'); + assert!(owner == dispatcher.get_contract_owner(), "Mr. Sensei should be the owner"); } #[test] diff --git a/exercises/starknet/basics/starknet4.cairo b/exercises/starknet/basics/starknet4.cairo index dcb122610..7d6722a3e 100644 --- a/exercises/starknet/basics/starknet4.cairo +++ b/exercises/starknet/basics/starknet4.cairo @@ -75,7 +75,7 @@ mod test { // Check that contract owner is set let contract_owner = dispatcher.get_owner(); - assert(contract_owner == owner, 'Elizabeth should be the owner'); + assert!(contract_owner == owner, "Elizabeth should be the owner"); } #[test] @@ -89,11 +89,11 @@ mod test { // Add stock dispatcher.add_stock('Nano', 10); let stock = dispatcher.get_stock('Nano'); - assert(stock == 10, 'stock should be 10'); + assert!(stock == 10, "stock should be 10"); dispatcher.add_stock('Nano', 15); let stock = dispatcher.get_stock('Nano'); - assert(stock == 25, 'stock should be 25'); + assert!(stock == 25, "stock should be 25"); stop_cheat_caller_address(dispatcher.contract_address); } @@ -108,7 +108,7 @@ mod test { // Add stock dispatcher.add_stock('Nano', 10); let stock = dispatcher.get_stock('Nano'); - assert(stock == 10, 'stock should be 10'); + assert!(stock == 10, "stock should be 10"); // Call contract as different address stop_cheat_caller_address(dispatcher.contract_address); @@ -116,7 +116,7 @@ mod test { dispatcher.purchase('Nano', 2); let stock = dispatcher.get_stock('Nano'); - assert(stock == 8, 'stock should be 8'); + assert!(stock == 8, "stock should be 8"); stop_cheat_caller_address(dispatcher.contract_address); } diff --git a/exercises/starknet/interoperability/starknet5.cairo b/exercises/starknet/interoperability/starknet5.cairo index c9e3d5ec9..31c622812 100644 --- a/exercises/starknet/interoperability/starknet5.cairo +++ b/exercises/starknet/interoperability/starknet5.cairo @@ -103,8 +103,8 @@ mod test { //TODO interact with contract_b to make the test pass. // Tests - assert(contract_a.set_value(300) == true, 'Could not set value'); - assert(contract_a.get_value() == 300, 'Value was not set'); - assert(contract_b.is_enabled() == true, 'Contract b is not enabled'); + assert!(contract_a.set_value(300) == true, "Could not set value"); + assert!(contract_a.get_value() == 300, "Value was not set"); + assert!(contract_b.is_enabled() == true, "Contract b is not enabled"); } } diff --git a/exercises/structs/structs2.cairo b/exercises/structs/structs2.cairo index 78fb6b20c..e52050914 100644 --- a/exercises/structs/structs2.cairo +++ b/exercises/structs/structs2.cairo @@ -31,11 +31,11 @@ fn test_your_order() { // TODO: Destructure your order into multiple variables to make the assertions pass! // let ... - assert(name == 'Bob', 'Wrong name'); - assert(year == order_template.year, 'Wrong year'); - assert(made_by_phone == order_template.made_by_phone, 'Wrong phone'); - assert(made_by_mobile == order_template.made_by_mobile, 'Wrong mobile'); - assert(made_by_email == order_template.made_by_email, 'Wrong email'); - assert(item_number == order_template.item_number, 'Wrong item number'); - assert(count == 0, 'Wrong count'); + assert!(name == 'Bob', "Wrong name"); + assert!(year == order_template.year, "Wrong year"); + assert!(made_by_phone == order_template.made_by_phone, "Wrong phone"); + assert!(made_by_mobile == order_template.made_by_mobile, "Wrong mobile"); + assert!(made_by_email == order_template.made_by_email, "Wrong email"); + assert!(item_number == order_template.item_number, "Wrong item number"); + assert!(count == 0, "Wrong count"); } diff --git a/exercises/structs/structs3.cairo b/exercises/structs/structs3.cairo index acc7fc800..222f3ad68 100644 --- a/exercises/structs/structs3.cairo +++ b/exercises/structs/structs3.cairo @@ -54,7 +54,7 @@ fn create_international_package() { let mut package = PackageTrait::new(sender_country, recipient_country, 1200); - assert(package.is_international() == true, 'Not international'); + assert!(package.is_international() == true, "Not international"); } #[cfg(test)] @@ -65,7 +65,7 @@ fn create_local_package() { let mut package = PackageTrait::new(sender_country, recipient_country, 1200); - assert(package.is_international() == false, 'International'); + assert!(package.is_international() == false, "International"); } #[cfg(test)] @@ -78,5 +78,5 @@ fn calculate_transport_fees() { let mut package = PackageTrait::new(sender_country, recipient_country, 1500); - assert(package.get_fees(cents_per_gram) == 4500, 'Wrong fees'); + assert!(package.get_fees(cents_per_gram) == 4500, "Wrong fees"); } diff --git a/exercises/traits/traits1.cairo b/exercises/traits/traits1.cairo index 1d1dabde8..e54ba1b2d 100644 --- a/exercises/traits/traits1.cairo +++ b/exercises/traits/traits1.cairo @@ -27,6 +27,6 @@ fn test_traits1() { // TODO make the test pass by creating two instances of Animal // and calling make_noise on them - assert(cat.make_noise() == 'meow', 'Wrong noise'); - assert(cow.make_noise() == 'moo', 'Wrong noise'); + assert!(cat.make_noise() == 'meow', "Wrong noise"); + assert!(cow.make_noise() == 'moo', "Wrong noise"); } diff --git a/exercises/traits/traits2.cairo b/exercises/traits/traits2.cairo index ebe90222a..cc8d9fde2 100644 --- a/exercises/traits/traits2.cairo +++ b/exercises/traits/traits2.cairo @@ -37,8 +37,8 @@ impl CatImpl of AnimalTrait { // TODO: implement the trait Animal for the t #[test] fn test_traits2() { let kitty: Cat = AnimalTrait::new(); - assert(kitty.make_noise() == 'meow', 'Wrong noise'); + assert!(kitty.make_noise() == 'meow', "Wrong noise"); let cow: Cow = AnimalTrait::new(); - assert(cow.make_noise() == 'moo', 'Wrong noise'); + assert!(cow.make_noise() == 'moo', "Wrong noise"); } diff --git a/exercises/traits/traits3.cairo b/exercises/traits/traits3.cairo index 1ce21ad23..da19b3e93 100644 --- a/exercises/traits/traits3.cairo +++ b/exercises/traits/traits3.cairo @@ -66,11 +66,11 @@ fn test_traits3() { // Don't modify this test! let mut salmon: Fish = AnimalTrait::new(); salmon.swim(); - assert(salmon.make_noise() == 'blub', 'Wrong noise'); - assert(salmon.get_distance() == 1, 'Wrong distance'); + assert!(salmon.make_noise() == 'blub', "Wrong noise"); + assert!(salmon.get_distance() == 1, "Wrong distance"); let mut dog: Dog = AnimalTrait::new(); dog.walk(); - assert(dog.make_noise() == 'woof', 'Wrong noise'); - assert(dog.get_distance() == 1, 'Wrong distance'); + assert!(dog.make_noise() == 'woof', "Wrong noise"); + assert!(dog.get_distance() == 1, "Wrong distance"); } diff --git a/solutions/arrays/arrays1.cairo b/solutions/arrays/arrays1.cairo index 35bea9429..23636264c 100644 --- a/solutions/arrays/arrays1.cairo +++ b/solutions/arrays/arrays1.cairo @@ -16,6 +16,6 @@ fn create_array() -> Array { #[test] fn test_array_len() { let mut a = create_array(); - assert(a.len() == 3, 'Array length is not 3'); - assert(a.pop_front().unwrap() == 0, 'First element is not 0'); + assert!(a.len() == 3, "Array length is not 3"); + assert!(a.pop_front().unwrap() == 0, "First element is not 0"); } diff --git a/solutions/arrays/arrays2.cairo b/solutions/arrays/arrays2.cairo index 6909708ff..05bda7e3b 100644 --- a/solutions/arrays/arrays2.cairo +++ b/solutions/arrays/arrays2.cairo @@ -18,8 +18,8 @@ fn remove_element_from_array(ref a: Array) { #[test] fn test_arrays2() { let mut a = create_array(); - assert(a.len() == 1, 'Array should have one element'); - assert(*a.at(0) == 42, 'First element should be 42'); + assert!(a.len() == 1, "Array should have one element"); + assert!(*a.at(0) == 42, "First element should be 42"); } #[cfg(test)] @@ -27,5 +27,5 @@ fn test_arrays2() { fn test_arrays2_empty() { let mut a = create_array(); remove_element_from_array(ref a); - assert(a.len() == 0, 'Array length is not 0'); + assert!(a.len() == 0, "Array length is not 0"); } diff --git a/solutions/dict/dict1.cairo b/solutions/dict/dict1.cairo index 7ddd9d380..c8437a0dc 100644 --- a/solutions/dict/dict1.cairo +++ b/solutions/dict/dict1.cairo @@ -25,7 +25,7 @@ fn create_dictionary() -> Felt252Dict { #[test] fn test_dict() { let mut dict = create_dictionary(); - assert(dict.get('A') == 1, 'First element is not 1'); - assert(dict.get('B') == 2, 'Second element is not 2'); - assert(dict.get('bob') == 3, 'Third element is not 3'); + assert!(dict.get('A') == 1, "First element is not 1"); + assert!(dict.get('B') == 2, "Second element is not 2"); + assert!(dict.get('bob') == 3, "Third element is not 3"); } diff --git a/solutions/dict/dict2.cairo b/solutions/dict/dict2.cairo index 64f7dba97..b750de72e 100644 --- a/solutions/dict/dict2.cairo +++ b/solutions/dict/dict2.cairo @@ -23,9 +23,9 @@ fn test_3() { multiply_element_by_10(ref dict, 3); - assert(dict.get(0) == 10, 'First element is not 10'); - assert(dict.get(1) == 20, 'Second element is not 20'); - assert(dict.get(2) == 30, 'Third element is not 30'); + assert!(dict.get(0) == 10, "First element is not 10"); + assert!(dict.get(1) == 20, "Second element is not 20"); + assert!(dict.get(2) == 30, "Third element is not 30"); } #[cfg(test)] @@ -39,7 +39,7 @@ fn test_4() { multiply_element_by_10(ref dict, 4); - assert(dict.get(2) == 50, 'First element is not 50'); - assert(dict.get(3) == 100, 'First element is not 100'); + assert!(dict.get(2) == 50, "First element is not 50"); + assert!(dict.get(3) == 100, "First element is not 100"); } diff --git a/solutions/dict/dict3.cairo b/solutions/dict/dict3.cairo index 14b6866a4..802f250fd 100644 --- a/solutions/dict/dict3.cairo +++ b/solutions/dict/dict3.cairo @@ -49,9 +49,9 @@ fn test_add_player() { team.add_player('bob', 10); team.add_player('alice', 20); - assert(team.players_count == 2, 'Wrong number of player'); - assert(team.get_level('bob') == 10, 'Wrong level'); - assert(team.get_level('alice') == 20, 'Wrong level'); + assert!(team.players_count == 2, "Wrong number of player"); + assert!(team.get_level('bob') == 10, "Wrong level"); + assert!(team.get_level('alice') == 20, "Wrong level"); } #[cfg(test)] @@ -61,5 +61,5 @@ fn test_level_up() { team.add_player('bobby', 10); team.level_up('bobby'); - assert(team.level.get('bobby') == 11, 'Wrong level'); + assert!(team.level.get('bobby') == 11, "Wrong level"); } diff --git a/solutions/enums/enums3.cairo b/solutions/enums/enums3.cairo index 0e3377047..3b9b9cc0d 100644 --- a/solutions/enums/enums3.cairo +++ b/solutions/enums/enums3.cairo @@ -72,7 +72,7 @@ fn test_match_message_call() { state.process(Message::Quit); assert(state.color == (255, 0, 255), 'wrong color'); - assert(state.position.x == 10, 'wrong x position'); - assert(state.position.y == 15, 'wrong y position'); - assert(state.quit, 'quit should be true'); + assert!(state.position.x == 10, "wrong x position"); + assert!(state.position.y == 15, "wrong y position"); + assert!(state.quit, "quit should be true"); } diff --git a/solutions/if/if2.cairo b/solutions/if/if2.cairo index f7495f5b6..16bcb1712 100644 --- a/solutions/if/if2.cairo +++ b/solutions/if/if2.cairo @@ -25,16 +25,16 @@ mod tests { #[test] fn foo_for_fizz() { - assert(foo_if_fizz('fizz') == 'foo', 'fizz returns foo') + assert!(foo_if_fizz('fizz') == 'foo', "fizz returns foo") } #[test] fn bar_for_fuzz() { - assert(foo_if_fizz('fuzz') == 'bar', 'fuzz returns bar'); + assert!(foo_if_fizz('fuzz') == 'bar', "fuzz returns bar"); } #[test] fn default_to_baz() { - assert(foo_if_fizz('literally anything') == 'baz', 'anything else returns baz'); + assert!(foo_if_fizz('literally anything') == 'baz', "anything else returns baz"); } } diff --git a/solutions/loops/loops1.cairo b/solutions/loops/loops1.cairo index 723be5650..aa6ac996a 100644 --- a/solutions/loops/loops1.cairo +++ b/solutions/loops/loops1.cairo @@ -12,5 +12,5 @@ fn test_loop() { break (); } }; - assert(counter == 10, 'counter should be 10') + assert!(counter == 10, "counter should be 10") } diff --git a/solutions/loops/loops2.cairo b/solutions/loops/loops2.cairo index 0e44be8c3..6ce98c453 100644 --- a/solutions/loops/loops2.cairo +++ b/solutions/loops/loops2.cairo @@ -14,5 +14,5 @@ fn test_loop() { counter += 1; }; - assert(result == 5, 'result should be 5'); + assert!(result == 5, "result should be 5"); } diff --git a/solutions/modules/modules1.cairo b/solutions/modules/modules1.cairo index 4a8fbe89d..44799bed4 100644 --- a/solutions/modules/modules1.cairo +++ b/solutions/modules/modules1.cairo @@ -14,7 +14,7 @@ fn test_mod_fn() { // Fix this line to call take_order function from module let order_result = restaurant::take_order(); - assert(order_result == 'order_taken', 'Order not taken'); + assert!(order_result == 'order_taken', "Order not taken"); } #[cfg(test)] @@ -24,6 +24,6 @@ mod tests { // Fix this line to call take_order function let order_result = super::restaurant::take_order(); - assert(order_result == 'order_taken', 'Order not taken'); + assert!(order_result == 'order_taken', "Order not taken"); } } diff --git a/solutions/modules/modules2.cairo b/solutions/modules/modules2.cairo index 7bc32398b..0b7082d45 100644 --- a/solutions/modules/modules2.cairo +++ b/solutions/modules/modules2.cairo @@ -43,9 +43,9 @@ pub mod order_utils { fn test_array() { let order1 = order_utils::dummy_phoned_order('John Doe'); let fees1 = order_utils::order_fees(order1); - assert(fees1 == 500, 'Order fee should be 500'); + assert!(fees1 == 500, "Order fee should be 500"); let order2 = order_utils::dummy_emailed_order('Jane Doe'); let fees2 = order_utils::order_fees(order2); - assert(fees2 == 200, 'Order fee should be 200'); + assert!(fees2 == 200, "Order fee should be 200"); } diff --git a/solutions/operations/operations1.cairo b/solutions/operations/operations1.cairo index 222e45368..9839bb807 100644 --- a/solutions/operations/operations1.cairo +++ b/solutions/operations/operations1.cairo @@ -16,11 +16,11 @@ fn poly(x: usize, y: usize) -> usize { #[test] fn test_poly() { let res = poly(5, 3); - assert(res == 126, 'Error message'); - assert(res < 300, 'res < 300'); - assert(res <= 300, 'res <= 300'); - assert(res > 20, 'res > 20'); - assert(res >= 2, 'res >= 2'); - assert(res != 27, 'res != 27'); - assert(res % 2 == 0, 'res %2 != 0'); + assert!(res == 126, "Error message"); + assert!(res < 300, "res < 300"); + assert!(res <= 300, "res <= 300"); + assert!(res > 20, "res > 20"); + assert!(res >= 2, "res >= 2"); + assert!(res != 27, "res != 27"); + assert!(res % 2 == 0, "res %2 != 0"); } diff --git a/solutions/operations/operations2.cairo b/solutions/operations/operations2.cairo index fc7b2b448..74c4ca6fa 100644 --- a/solutions/operations/operations2.cairo +++ b/solutions/operations/operations2.cairo @@ -24,30 +24,30 @@ fn multiplication(x: u64, y: u64) -> u64 { #[test] fn test_modulus() { let res = modulus(16, 2); - assert(res == 0, 'Error message'); + assert!(res == 0, "Error message"); let res = modulus(17, 3); - assert(res == 2, 'Error message'); + assert!(res == 2, "Error message"); } #[cfg(test)] #[test] fn test_floor_division() { let res = floor_division(160, 2); - assert(res == 80, 'Error message'); + assert!(res == 80, "Error message"); let res = floor_division(21, 4); - assert(res == 5, 'Error message'); + assert!(res == 5, "Error message"); } #[cfg(test)] #[test] fn test_mul() { let res = multiplication(16, 2); - assert(res == 32, 'Error message'); + assert!(res == 32, "Error message"); let res = multiplication(21, 4); - assert(res == 84, 'Error message'); + assert!(res == 84, "Error message"); } #[cfg(test)] diff --git a/solutions/options/options1.cairo b/solutions/options/options1.cairo index d1d56e459..452951ebe 100644 --- a/solutions/options/options1.cairo +++ b/solutions/options/options1.cairo @@ -21,11 +21,11 @@ fn maybe_icecream( #[cfg(test)] #[test] fn check_icecream() { - assert(maybe_icecream(9).unwrap() == 5, 'err_1'); - assert(maybe_icecream(10).unwrap() == 5, 'err_2'); - assert(maybe_icecream(23).unwrap() == 0, 'err_3'); - assert(maybe_icecream(22).unwrap() == 0, 'err_4'); - assert(maybe_icecream(25).is_none(), 'err_5'); + assert!(maybe_icecream(9).unwrap() == 5, "err_1"); + assert!(maybe_icecream(10).unwrap() == 5, "err_2"); + assert!(maybe_icecream(23).unwrap() == 0, "err_3"); + assert!(maybe_icecream(22).unwrap() == 0, "err_4"); + assert!(maybe_icecream(25).is_none(), "err_5"); } #[cfg(test)] @@ -33,5 +33,5 @@ fn check_icecream() { fn raw_value() { // TODO: Fix this test. How do you get at the value contained in the Option? let icecreams = maybe_icecream(12); - assert(icecreams.unwrap() == 5, 'err_6'); + assert!(icecreams.unwrap() == 5, "err_6"); } diff --git a/solutions/primitive_types/primitive_types4.cairo b/solutions/primitive_types/primitive_types4.cairo index 2072e6e9c..3fa31f774 100644 --- a/solutions/primitive_types/primitive_types4.cairo +++ b/solutions/primitive_types/primitive_types4.cairo @@ -38,11 +38,11 @@ fn test_sum_big_numbers() { #[cfg(test)] #[test] fn test_convert_to_felt() { - assert(convert_to_felt(1_u8) == 1, 'Type conversion went wrong'); + assert!(convert_to_felt(1_u8) == 1, "Type conversion went wrong"); } #[cfg(test)] #[test] fn test_convert_to_u8() { - assert(convert_felt_to_u8(1) == 1_u8, 'Type conversion went wrong'); + assert!(convert_felt_to_u8(1) == 1_u8, "Type conversion went wrong"); } diff --git a/solutions/quizs/quizs1.cairo b/solutions/quizs/quizs1.cairo index 27c0000de..de8456b58 100644 --- a/solutions/quizs/quizs1.cairo +++ b/solutions/quizs/quizs1.cairo @@ -21,8 +21,8 @@ fn verify_test() { let price3 = calculate_price_of_apples(41); let price4 = calculate_price_of_apples(65); - assert(105 == price1, 'Incorrect price'); - assert(120 == price2, 'Incorrect price'); - assert(82 == price3, 'Incorrect price'); - assert(130 == price4, 'Incorrect price'); + assert!(105 == price1, "Incorrect price"); + assert!(120 == price2, "Incorrect price"); + assert!(82 == price3, "Incorrect price"); + assert!(130 == price4, "Incorrect price"); } diff --git a/solutions/starknet/basics/starknet1.cairo b/solutions/starknet/basics/starknet1.cairo index b58a640bf..09f6ef577 100644 --- a/solutions/starknet/basics/starknet1.cairo +++ b/solutions/starknet/basics/starknet1.cairo @@ -30,7 +30,7 @@ mod test { #[test] fn test_contract_view() { let dispatcher = deploy_contract(); - assert('Joe' == dispatcher.get_owner(), 'Joe should be the owner.'); + assert!('Joe' == dispatcher.get_owner(), "Joe should be the owner."); } fn deploy_contract() -> IJoesContractDispatcher { diff --git a/solutions/starknet/basics/starknet2.cairo b/solutions/starknet/basics/starknet2.cairo index 23a1ea339..02b9c3d47 100644 --- a/solutions/starknet/basics/starknet2.cairo +++ b/solutions/starknet/basics/starknet2.cairo @@ -53,6 +53,6 @@ mod test { let (contract_address, _) = contract.deploy(@calldata).unwrap(); let dispatcher = IJillsContractDispatcher { contract_address }; let owner = dispatcher.get_owner(); - assert(owner == 'Jill'.try_into().unwrap(), 'Owner should be Jill'); + assert!(owner == 'Jill'.try_into().unwrap(), "Owner should be Jill"); } } diff --git a/solutions/starknet/basics/starknet3.cairo b/solutions/starknet/basics/starknet3.cairo index af21fe2ad..23e399b03 100644 --- a/solutions/starknet/basics/starknet3.cairo +++ b/solutions/starknet/basics/starknet3.cairo @@ -39,7 +39,7 @@ mod ProgressTracker { // Assert owner is calling let caller = get_caller_address(); let owner = self.contract_owner.read(); - assert(caller == owner, 'Only owner can set progress'); + assert!(caller == owner, "Only owner can set progress"); // Set new_progress for user self.progress.write(user, new_progress); @@ -68,7 +68,7 @@ mod test { fn test_owner() { let owner: ContractAddress = 'Sensei'.try_into().unwrap(); let dispatcher = deploy_contract(); - assert(owner == dispatcher.get_contract_owner(), 'Mr. Sensei should be the owner'); + assert!(owner == dispatcher.get_contract_owner(), "Mr. Sensei should be the owner"); } #[test] diff --git a/solutions/starknet/basics/starknet4.cairo b/solutions/starknet/basics/starknet4.cairo index 9e611b83d..039e83fff 100644 --- a/solutions/starknet/basics/starknet4.cairo +++ b/solutions/starknet/basics/starknet4.cairo @@ -36,7 +36,7 @@ mod LizInventory { // Only owner can call this let caller = get_caller_address(); let owner = self.contract_owner.read(); - assert(caller == owner, 'Only owner can add stock'); + assert!(caller == owner, "Only owner can add stock"); // Add new_stock to existing stock in inventory let current_stock = self.inventory.entry(product).read(); @@ -48,7 +48,7 @@ mod LizInventory { // Anybody can call this // Subtract quantity from stock in inventory let current_stock = self.inventory.entry(product).read(); - assert(current_stock >= quantity, 'Insufficient stock'); + assert!(current_stock >= quantity, "Insufficient stock"); let updated_stock = current_stock - quantity; self.inventory.entry(product).write(updated_stock); @@ -80,7 +80,7 @@ mod test { // Check that contract owner is set let contract_owner = dispatcher.get_owner(); - assert(contract_owner == owner, 'Elizabeth should be the owner'); + assert!(contract_owner == owner, "Elizabeth should be the owner"); } #[test] @@ -94,11 +94,11 @@ mod test { // Add stock dispatcher.add_stock('Nano', 10); let stock = dispatcher.get_stock('Nano'); - assert(stock == 10, 'stock should be 10'); + assert!(stock == 10, "stock should be 10"); dispatcher.add_stock('Nano', 15); let stock = dispatcher.get_stock('Nano'); - assert(stock == 25, 'stock should be 25'); + assert!(stock == 25, "stock should be 25"); stop_cheat_caller_address(dispatcher.contract_address); } @@ -113,7 +113,7 @@ mod test { // Add stock dispatcher.add_stock('Nano', 10); let stock = dispatcher.get_stock('Nano'); - assert(stock == 10, 'stock should be 10'); + assert!(stock == 10, "stock should be 10"); // Call contract as different address stop_cheat_caller_address(dispatcher.contract_address); @@ -121,7 +121,7 @@ mod test { dispatcher.purchase('Nano', 2); let stock = dispatcher.get_stock('Nano'); - assert(stock == 8, 'stock should be 8'); + assert!(stock == 8, "stock should be 8"); stop_cheat_caller_address(dispatcher.contract_address); } diff --git a/solutions/starknet/interoperability/starknet5.cairo b/solutions/starknet/interoperability/starknet5.cairo index 5babb270a..ce149d310 100644 --- a/solutions/starknet/interoperability/starknet5.cairo +++ b/solutions/starknet/interoperability/starknet5.cairo @@ -114,8 +114,8 @@ mod test { contract_b.enable(); // Tests - assert(contract_a.set_value(300) == true, 'Could not set value'); - assert(contract_a.get_value() == 300, 'Value was not set'); - assert(contract_b.is_enabled() == true, 'Contract b is not enabled'); + assert!(contract_a.set_value(300) == true, "Could not set value"); + assert!(contract_a.get_value() == 300, "Value was not set"); + assert!(contract_b.is_enabled() == true, "Contract b is not enabled"); } } diff --git a/solutions/structs/structs2.cairo b/solutions/structs/structs2.cairo index 79531fe93..24892c753 100644 --- a/solutions/structs/structs2.cairo +++ b/solutions/structs/structs2.cairo @@ -29,11 +29,11 @@ fn test_your_order() { // TODO: Destructure your order into multiple variables to make the assertions pass! let Order { name, year, made_by_phone, made_by_mobile, made_by_email, item_number, count } = order_template; - assert(name == 'Bob', 'Wrong name'); - assert(year == order_template.year, 'Wrong year'); - assert(made_by_phone == order_template.made_by_phone, 'Wrong phone'); - assert(made_by_mobile == order_template.made_by_mobile, 'Wrong mobile'); - assert(made_by_email == order_template.made_by_email, 'Wrong email'); - assert(item_number == order_template.item_number, 'Wrong item number'); - assert(count == 0, 'Wrong count'); + assert!(name == 'Bob', "Wrong name"); + assert!(year == order_template.year, "Wrong year"); + assert!(made_by_phone == order_template.made_by_phone, "Wrong phone"); + assert!(made_by_mobile == order_template.made_by_mobile, "Wrong mobile"); + assert!(made_by_email == order_template.made_by_email, "Wrong email"); + assert!(item_number == order_template.item_number, "Wrong item number"); + assert!(count == 0, "Wrong count"); } diff --git a/solutions/structs/structs3.cairo b/solutions/structs/structs3.cairo index d491bba33..d754767b7 100644 --- a/solutions/structs/structs3.cairo +++ b/solutions/structs/structs3.cairo @@ -50,7 +50,7 @@ fn create_international_package() { let mut package = PackageTrait::new(sender_country, recipient_country, 1200); - assert(package.is_international() == true, 'Not international'); + assert!(package.is_international() == true, "Not international"); } #[cfg(test)] @@ -61,7 +61,7 @@ fn create_local_package() { let mut package = PackageTrait::new(sender_country, recipient_country, 1200); - assert(package.is_international() == false, 'International'); + assert!(package.is_international() == false, "International"); } #[cfg(test)] @@ -74,5 +74,5 @@ fn calculate_transport_fees() { let mut package = PackageTrait::new(sender_country, recipient_country, 1500); - assert(package.get_fees(cents_per_gram) == 4500, 'Wrong fees'); + assert!(package.get_fees(cents_per_gram) == 4500, "Wrong fees"); } diff --git a/solutions/traits/traits1.cairo b/solutions/traits/traits1.cairo index 3a37e335f..0d7ca7119 100644 --- a/solutions/traits/traits1.cairo +++ b/solutions/traits/traits1.cairo @@ -36,6 +36,6 @@ fn test_traits1() { let cat = AnimalTrait::new('meow'); let cow = AnimalTrait::new('moo'); - assert(cat.make_noise() == 'meow', 'Wrong noise'); - assert(cow.make_noise() == 'moo', 'Wrong noise'); + assert!(cat.make_noise() == 'meow', "Wrong noise"); + assert!(cow.make_noise() == 'moo', "Wrong noise"); } diff --git a/solutions/traits/traits2.cairo b/solutions/traits/traits2.cairo index 240c536f8..072da793f 100644 --- a/solutions/traits/traits2.cairo +++ b/solutions/traits/traits2.cairo @@ -52,8 +52,8 @@ impl CowImpl of AnimalTrait { #[test] fn test_traits2() { let kitty: Cat = AnimalTrait::new(); - assert(kitty.make_noise() == 'meow', 'Wrong noise'); + assert!(kitty.make_noise() == 'meow', "Wrong noise"); let cow: Cow = AnimalTrait::new(); - assert(cow.make_noise() == 'moo', 'Wrong noise'); + assert!(cow.make_noise() == 'moo', "Wrong noise"); } diff --git a/solutions/traits/traits3.cairo b/solutions/traits/traits3.cairo index 1468ca5b0..3f9d3a3a9 100644 --- a/solutions/traits/traits3.cairo +++ b/solutions/traits/traits3.cairo @@ -73,11 +73,11 @@ fn test_traits3() { // Don't modify this test! let mut salmon: Fish = AnimalTrait::new(); salmon.swim(); - assert(salmon.make_noise() == 'blub', 'Wrong noise'); - assert(salmon.get_distance() == 1, 'Wrong distance'); + assert!(salmon.make_noise() == 'blub', "Wrong noise"); + assert!(salmon.get_distance() == 1, "Wrong distance"); let mut dog: Dog = AnimalTrait::new(); dog.walk(); - assert(dog.make_noise() == 'woof', 'Wrong noise'); - assert(dog.get_distance() == 1, 'Wrong distance'); + assert!(dog.make_noise() == 'woof', "Wrong noise"); + assert!(dog.get_distance() == 1, "Wrong distance"); } From 8a629a88d569a0a160d9250c59ba408a92560e0b Mon Sep 17 00:00:00 2001 From: enitrat Date: Thu, 17 Jul 2025 20:18:12 +0100 Subject: [PATCH 07/12] fix move_semantics2 solution --- solutions/move_semantics/move_semantics2.cairo | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/solutions/move_semantics/move_semantics2.cairo b/solutions/move_semantics/move_semantics2.cairo index 5e4e0eae3..729ccc8e5 100644 --- a/solutions/move_semantics/move_semantics2.cairo +++ b/solutions/move_semantics/move_semantics2.cairo @@ -2,9 +2,9 @@ fn main() { - let arr0 = ArrayTrait::new(); + let mut arr0 = ArrayTrait::new(); - let mut arr1 = fill_arr(arr0); + fill_arr(ref arr0); // Do not change the following line! print_arr(arr0); @@ -15,12 +15,8 @@ fn print_arr(arr: Array) { } // Do not change the following line! -fn fill_arr(arr: Array) -> Array { - let mut arr = arr; - +fn fill_arr(ref arr: Array){ arr.append(22); arr.append(44); arr.append(66); - - arr } From dfc5fc67b0bc16320ecbcddf86b0a2e77a3111e0 Mon Sep 17 00:00:00 2001 From: enitrat Date: Sun, 20 Jul 2025 18:21:46 +0100 Subject: [PATCH 08/12] update outdated panic usage --- exercises/structs/structs3.cairo | 6 +----- solutions/structs/structs3.cairo | 6 +----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/exercises/structs/structs3.cairo b/exercises/structs/structs3.cairo index 222f3ad68..8bc812fbf 100644 --- a/exercises/structs/structs3.cairo +++ b/exercises/structs/structs3.cairo @@ -18,11 +18,7 @@ trait PackageTrait { } impl PackageImpl of PackageTrait { fn new(sender_country: felt252, recipient_country: felt252, weight_in_grams: usize) -> Package { - if weight_in_grams <= 0{ - let mut data = ArrayTrait::new(); - data.append('x'); - panic(data); - } + assert!(weight_in_grams > 0, "Weight must be greater than 0"); Package { sender_country, recipient_country, weight_in_grams, } } diff --git a/solutions/structs/structs3.cairo b/solutions/structs/structs3.cairo index d754767b7..2a2a54451 100644 --- a/solutions/structs/structs3.cairo +++ b/solutions/structs/structs3.cairo @@ -16,11 +16,7 @@ trait PackageTrait { } impl PackageImpl of PackageTrait { fn new(sender_country: felt252, recipient_country: felt252, weight_in_grams: usize) -> Package { - if weight_in_grams <= 0{ - let mut data = ArrayTrait::new(); - data.append('x'); - panic(data); - } + assert!(weight_in_grams > 0, "Weight must be greater than 0"); Package { sender_country, recipient_country, weight_in_grams, } } From 814004201aba94defb4fb1a860b38eb4c839a1ff Mon Sep 17 00:00:00 2001 From: enitrat Date: Sat, 2 Aug 2025 22:54:07 +0100 Subject: [PATCH 09/12] update ci --- .github/workflows/rust.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index ce989d799..fb78f1646 100755 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -17,7 +17,7 @@ jobs: - name: Setup Rust v1.80.1 run: rustup default 1.80.1 - name: Install all Cairo tools - run: curl --proto '=https' --tlsv1.2 -sSf https://sh.starkup.sh | sh -s -- --version-set latest + run: curl --proto '=https' --tlsv1.2 -sSf https://sh.starkup.sh | sh -s -- --version-set latest --yes - name: Build run: cargo build --verbose - name: Run tests From 54b77166a4344f870f7d98422b83790d66e6ff47 Mon Sep 17 00:00:00 2001 From: enitrat Date: Tue, 5 Aug 2025 18:31:20 +0100 Subject: [PATCH 10/12] update intro exercises and bump cairo --- exercises/intro/intro1.cairo | 18 +++++++++++++++++- exercises/intro/intro2.cairo | 5 ++++- runner-crate/.tool-versions | 2 ++ runner-crate/Scarb.lock | 8 ++++---- runner-crate/Scarb.toml | 6 +++--- solutions/intro/intro1.cairo | 18 +++++++++++++++++- solutions/intro/intro2.cairo | 2 +- 7 files changed, 48 insertions(+), 11 deletions(-) create mode 100644 runner-crate/.tool-versions diff --git a/exercises/intro/intro1.cairo b/exercises/intro/intro1.cairo index dd4e52ad1..096ccbb02 100644 --- a/exercises/intro/intro1.cairo +++ b/exercises/intro/intro1.cairo @@ -4,4 +4,20 @@ // I AM NOT DONE -fn main() {} +fn main() { + println!(" Welcome to... "); + println!(" _ _ _ _ "); + println!(" ___| |_ __ _ _ __| | _| (_)_ __ __ _ ___ "); + println!(" / __| __/ _` | '__| |/ / | | '_ / / _` / __|"); + println!(" |__ / || (_| | | | <| | | | | | (_| |__ "); + println!(" |___/__/__,_|_| |_|/_/_|_|_| |_|/__, |___/"); + println!(" |___/ "); + println!("\n"); + println!("This exercise compiles successfully. The remaining exercises contain a compiler"); + println!("or logic error. The central concept behind Starklings is to fix these errors and"); + println!("solve the exercises. Good luck!"); + println!("\n"); + println!("The file of this exercise is `exercises/intro/intro1.cairo`. Have a look!"); + println!("The current exercise path will be always shown under the progress bar."); + println!("You can click on the path to open the exercise file in your editor."); +} diff --git a/exercises/intro/intro2.cairo b/exercises/intro/intro2.cairo index 29604faa8..d7fc6b3ad 100644 --- a/exercises/intro/intro2.cairo +++ b/exercises/intro/intro2.cairo @@ -1,4 +1,7 @@ // I AM NOT DONE // This exercise won't compile... Can you make it compile? - +fn main() { + // TODO: Fix the code to print "Hello world!". + printline!("Hello world!"); +} diff --git a/runner-crate/.tool-versions b/runner-crate/.tool-versions new file mode 100644 index 000000000..b9a86e384 --- /dev/null +++ b/runner-crate/.tool-versions @@ -0,0 +1,2 @@ +scarb 2.12.0 +starknet-foundry 0.47.0 diff --git a/runner-crate/Scarb.lock b/runner-crate/Scarb.lock index f603c1903..60192ae2a 100644 --- a/runner-crate/Scarb.lock +++ b/runner-crate/Scarb.lock @@ -10,15 +10,15 @@ dependencies = [ [[package]] name = "snforge_scarb_plugin" -version = "0.44.0" +version = "0.47.0" source = "registry+https://scarbs.xyz/" -checksum = "sha256:ec8c7637b33392a53153c1e5b87a4617ddcb1981951b233ea043cad5136697e2" +checksum = "sha256:3525e4502541043571678531fced28f753746cb59a8aa79811811218abef6c05" [[package]] name = "snforge_std" -version = "0.44.0" +version = "0.47.0" source = "registry+https://scarbs.xyz/" -checksum = "sha256:d4affedfb90715b1ac417b915c0a63377ae6dd69432040e5d933130d65114702" +checksum = "sha256:b8647adcd0f5c9631f88b5a523b2653a82f2349dde2af7213c75f1006fa3f71b" dependencies = [ "snforge_scarb_plugin", ] diff --git a/runner-crate/Scarb.toml b/runner-crate/Scarb.toml index 5df48ba2a..ebd9ffd6f 100644 --- a/runner-crate/Scarb.toml +++ b/runner-crate/Scarb.toml @@ -11,10 +11,10 @@ allow-prebuilt-plugins = ["snforge_std"] # Core Starknet dependencies [dependencies] -starknet = "2.11.4" +starknet = "2.12.0" [dev-dependencies] -snforge_std = "0.44.0" +snforge_std = "0.47.0" assert_macros = "2.11.4" -# Starknet contract compilation target \ No newline at end of file +# Starknet contract compilation target diff --git a/solutions/intro/intro1.cairo b/solutions/intro/intro1.cairo index 866976ce8..8dee99f1c 100644 --- a/solutions/intro/intro1.cairo +++ b/solutions/intro/intro1.cairo @@ -2,4 +2,20 @@ // needs to have a `main` function. So this file is a valid Cairo file. // Other exercises will require you to write Cairo code to make the exercise file compile. -fn main() {} +fn main() { + println!(" Welcome to... "); + println!(" _ _ _ _ "); + println!(" ___| |_ __ _ _ __| | _| (_)_ __ __ _ ___ "); + println!(" / __| __/ _` | '__| |/ / | | '_ / / _` / __|"); + println!(" |__ / || (_| | | | <| | | | | | (_| |__ "); + println!(" |___/__/__,_|_| |_|/_/_|_|_| |_|/__, |___/"); + println!(" |___/ "); + println!("\n"); + println!("This exercise compiles successfully. The remaining exercises contain a compiler"); + println!("or logic error. The central concept behind Starklings is to fix these errors and"); + println!("solve the exercises. Good luck!"); + println!("\n"); + println!("The file of this exercise is `exercises/intro/intro1.cairo`. Have a look!"); + println!("The current exercise path will be always shown under the progress bar."); + println!("You can click on the path to open the exercise file in your editor."); +} diff --git a/solutions/intro/intro2.cairo b/solutions/intro/intro2.cairo index a4553a38c..b8896a699 100644 --- a/solutions/intro/intro2.cairo +++ b/solutions/intro/intro2.cairo @@ -1,5 +1,5 @@ - // This exercise won't compile... Can you make it compile? fn main() { + println!("Hello world!"); } From b8c44e9f8386eaf52681d47c5f6de0a6b031fe32 Mon Sep 17 00:00:00 2001 From: enitrat Date: Tue, 9 Sep 2025 10:24:28 +0100 Subject: [PATCH 11/12] fix CI tests --- .github/workflows/rust.yml | 4 ++-- rust-toolchain | 2 +- tests/fixture/cairo/runner-crate/Scarb.toml | 4 +++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index fb78f1646..4940bf78f 100755 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -14,8 +14,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Setup Rust v1.80.1 - run: rustup default 1.80.1 + - name: Setup Rust toolchain + uses: dtolnay/rust-toolchain@stable - name: Install all Cairo tools run: curl --proto '=https' --tlsv1.2 -sSf https://sh.starkup.sh | sh -s -- --version-set latest --yes - name: Build diff --git a/rust-toolchain b/rust-toolchain index 06810703e..edc4de49c 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "1.86.0" +channel = "1.89.0" components = ["rustfmt", "clippy"] profile = "minimal" diff --git a/tests/fixture/cairo/runner-crate/Scarb.toml b/tests/fixture/cairo/runner-crate/Scarb.toml index 4b848bfd9..03549640d 100644 --- a/tests/fixture/cairo/runner-crate/Scarb.toml +++ b/tests/fixture/cairo/runner-crate/Scarb.toml @@ -3,7 +3,6 @@ name = "runner_crate" version = "0.1.0" edition = "2024_07" - [dependencies] starknet = "2.11.4" @@ -11,6 +10,9 @@ starknet = "2.11.4" snforge_std = "0.44.0" assert_macros = "2.11.4" +[lib] +sierra = true + [[target.starknet-contract]] sierra = true From e9fecba5a97e85ca0ca1912e0f239d1eccc82697 Mon Sep 17 00:00:00 2001 From: enitrat Date: Tue, 9 Sep 2025 12:07:45 +0100 Subject: [PATCH 12/12] update cairo to 2.12 --- .github/workflows/rust.yml | 2 ++ Scarb.lock | 24 --------------------- exercises/Scarb.lock | 24 --------------------- runner-crate/.tool-versions | 4 ++-- runner-crate/Scarb.lock | 8 +++---- runner-crate/Scarb.toml | 6 +++--- tests/fixture/cairo/runner-crate/Scarb.lock | 8 +++---- tests/fixture/cairo/runner-crate/Scarb.toml | 6 +++--- 8 files changed, 18 insertions(+), 64 deletions(-) delete mode 100644 Scarb.lock delete mode 100644 exercises/Scarb.lock diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 4940bf78f..fa8dc79f6 100755 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -18,6 +18,8 @@ jobs: uses: dtolnay/rust-toolchain@stable - name: Install all Cairo tools run: curl --proto '=https' --tlsv1.2 -sSf https://sh.starkup.sh | sh -s -- --version-set latest --yes + - name: Setup Starknet Foundry + uses: foundry-rs/setup-snfoundry@v3 - name: Build run: cargo build --verbose - name: Run tests diff --git a/Scarb.lock b/Scarb.lock deleted file mode 100644 index 594a8c539..000000000 --- a/Scarb.lock +++ /dev/null @@ -1,24 +0,0 @@ -# Code generated by scarb DO NOT EDIT. -version = 1 - -[[package]] -name = "snforge_scarb_plugin" -version = "0.44.0" -source = "registry+https://scarbs.xyz/" -checksum = "sha256:ec8c7637b33392a53153c1e5b87a4617ddcb1981951b233ea043cad5136697e2" - -[[package]] -name = "snforge_std" -version = "0.44.0" -source = "registry+https://scarbs.xyz/" -checksum = "sha256:d4affedfb90715b1ac417b915c0a63377ae6dd69432040e5d933130d65114702" -dependencies = [ - "snforge_scarb_plugin", -] - -[[package]] -name = "starklings_cairo1" -version = "0.1.0" -dependencies = [ - "snforge_std", -] diff --git a/exercises/Scarb.lock b/exercises/Scarb.lock deleted file mode 100644 index 594a8c539..000000000 --- a/exercises/Scarb.lock +++ /dev/null @@ -1,24 +0,0 @@ -# Code generated by scarb DO NOT EDIT. -version = 1 - -[[package]] -name = "snforge_scarb_plugin" -version = "0.44.0" -source = "registry+https://scarbs.xyz/" -checksum = "sha256:ec8c7637b33392a53153c1e5b87a4617ddcb1981951b233ea043cad5136697e2" - -[[package]] -name = "snforge_std" -version = "0.44.0" -source = "registry+https://scarbs.xyz/" -checksum = "sha256:d4affedfb90715b1ac417b915c0a63377ae6dd69432040e5d933130d65114702" -dependencies = [ - "snforge_scarb_plugin", -] - -[[package]] -name = "starklings_cairo1" -version = "0.1.0" -dependencies = [ - "snforge_std", -] diff --git a/runner-crate/.tool-versions b/runner-crate/.tool-versions index b9a86e384..2b21bb054 100644 --- a/runner-crate/.tool-versions +++ b/runner-crate/.tool-versions @@ -1,2 +1,2 @@ -scarb 2.12.0 -starknet-foundry 0.47.0 +scarb 2.12.1 +starknet-foundry 0.48.0 diff --git a/runner-crate/Scarb.lock b/runner-crate/Scarb.lock index 60192ae2a..a1c881702 100644 --- a/runner-crate/Scarb.lock +++ b/runner-crate/Scarb.lock @@ -10,15 +10,15 @@ dependencies = [ [[package]] name = "snforge_scarb_plugin" -version = "0.47.0" +version = "0.48.1" source = "registry+https://scarbs.xyz/" -checksum = "sha256:3525e4502541043571678531fced28f753746cb59a8aa79811811218abef6c05" +checksum = "sha256:2dd27e8215eea8785b3930e9f452e11b429ca262b1c1fbb071bfc173b9ebc125" [[package]] name = "snforge_std" -version = "0.47.0" +version = "0.48.1" source = "registry+https://scarbs.xyz/" -checksum = "sha256:b8647adcd0f5c9631f88b5a523b2653a82f2349dde2af7213c75f1006fa3f71b" +checksum = "sha256:89f759fa685d48ed0ba7152d2ac2eb168da08dfa8b84b2bee96e203dc5b2413e" dependencies = [ "snforge_scarb_plugin", ] diff --git a/runner-crate/Scarb.toml b/runner-crate/Scarb.toml index ebd9ffd6f..2ca35a9f6 100644 --- a/runner-crate/Scarb.toml +++ b/runner-crate/Scarb.toml @@ -11,10 +11,10 @@ allow-prebuilt-plugins = ["snforge_std"] # Core Starknet dependencies [dependencies] -starknet = "2.12.0" +starknet = "2.12.1" [dev-dependencies] -snforge_std = "0.47.0" -assert_macros = "2.11.4" +snforge_std = "0.48.0" +assert_macros = "2.12.1" # Starknet contract compilation target diff --git a/tests/fixture/cairo/runner-crate/Scarb.lock b/tests/fixture/cairo/runner-crate/Scarb.lock index f603c1903..a1c881702 100644 --- a/tests/fixture/cairo/runner-crate/Scarb.lock +++ b/tests/fixture/cairo/runner-crate/Scarb.lock @@ -10,15 +10,15 @@ dependencies = [ [[package]] name = "snforge_scarb_plugin" -version = "0.44.0" +version = "0.48.1" source = "registry+https://scarbs.xyz/" -checksum = "sha256:ec8c7637b33392a53153c1e5b87a4617ddcb1981951b233ea043cad5136697e2" +checksum = "sha256:2dd27e8215eea8785b3930e9f452e11b429ca262b1c1fbb071bfc173b9ebc125" [[package]] name = "snforge_std" -version = "0.44.0" +version = "0.48.1" source = "registry+https://scarbs.xyz/" -checksum = "sha256:d4affedfb90715b1ac417b915c0a63377ae6dd69432040e5d933130d65114702" +checksum = "sha256:89f759fa685d48ed0ba7152d2ac2eb168da08dfa8b84b2bee96e203dc5b2413e" dependencies = [ "snforge_scarb_plugin", ] diff --git a/tests/fixture/cairo/runner-crate/Scarb.toml b/tests/fixture/cairo/runner-crate/Scarb.toml index 03549640d..9bd432f2c 100644 --- a/tests/fixture/cairo/runner-crate/Scarb.toml +++ b/tests/fixture/cairo/runner-crate/Scarb.toml @@ -4,11 +4,11 @@ version = "0.1.0" edition = "2024_07" [dependencies] -starknet = "2.11.4" +starknet = "2.12.1" [dev-dependencies] -snforge_std = "0.44.0" -assert_macros = "2.11.4" +snforge_std = "0.48.0" +assert_macros = "2.12.1" [lib] sierra = true