diff --git a/Cargo.lock b/Cargo.lock index 70d6188c9..ed8496ec5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,17 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "ahash" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +dependencies = [ + "cfg-if 1.0.0", + "once_cell", + "version_check", +] + [[package]] name = "aho-corasick" version = "0.7.20" @@ -12,12 +23,52 @@ dependencies = [ ] [[package]] -name = "android_system_properties" -version = "0.1.5" +name = "anstream" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +checksum = "9e579a7752471abc2a8268df8b20005e3eadd975f585398f17efcfd8d4927371" dependencies = [ - "libc", + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is-terminal", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" + +[[package]] +name = "anstyle-parse" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "anstyle-wincon" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bcd8291a340dd8ac70e18878bc4501dd7b4ff970cfa21c207d36ece51ea88fd" +dependencies = [ + "anstyle", + "windows-sys 0.48.0", ] [[package]] @@ -222,22 +273,11 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" -[[package]] -name = "bigdecimal" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aaf33151a6429fe9211d1b276eafdf70cdff28b071e76c0b0e1503221ea3744" -dependencies = [ - "num-bigint", - "num-integer", - "num-traits 0.2.15", -] - [[package]] name = "bincode" -version = "1.3.3" +version = "2.0.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +checksum = "f11ea1a0346b94ef188834a65c068a03aec181c94896d481d7a0a40d85b0ce95" dependencies = [ "serde", ] @@ -264,12 +304,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] -name = "block-buffer" -version = "0.9.0" +name = "bitvec" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" dependencies = [ - "generic-array", + "funty", + "radium", + "tap", + "wyz", ] [[package]] @@ -289,9 +332,9 @@ checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" [[package]] name = "cairo-felt" -version = "0.1.3" +version = "0.3.0-rc1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "250f460db3bb8e8589812495fdca7301e9674b3a2c81f2380e9c07d914979a42" +checksum = "a93dedd19b8edf685798f1f12e4e0ac21ac196ea5262c300783f69f3fa0cb28b" dependencies = [ "lazy_static", "num-bigint", @@ -302,8 +345,8 @@ dependencies = [ [[package]] name = "cairo-lang-casm" -version = "1.0.0-alpha.6" -source = "git+https://github.com/starkware-libs/cairo?rev=v1.0.0-alpha.6#439da05a031c2eda263c4ce12d0b71d20f38205f" +version = "1.0.0-alpha.7" +source = "git+https://github.com/starkware-libs/cairo?rev=7b4bbf3d57230e0e307fbb634394f6e57b3c63cc#7b4bbf3d57230e0e307fbb634394f6e57b3c63cc" dependencies = [ "cairo-lang-utils", "indoc", @@ -315,8 +358,8 @@ dependencies = [ [[package]] name = "cairo-lang-compiler" -version = "1.0.0-alpha.6" -source = "git+https://github.com/starkware-libs/cairo?rev=v1.0.0-alpha.6#439da05a031c2eda263c4ce12d0b71d20f38205f" +version = "1.0.0-alpha.7" +source = "git+https://github.com/starkware-libs/cairo?rev=7b4bbf3d57230e0e307fbb634394f6e57b3c63cc#7b4bbf3d57230e0e307fbb634394f6e57b3c63cc" dependencies = [ "anyhow", "cairo-lang-defs", @@ -331,7 +374,7 @@ dependencies = [ "cairo-lang-sierra-generator", "cairo-lang-syntax", "cairo-lang-utils", - "clap 4.1.13", + "clap", "log", "salsa", "thiserror", @@ -339,13 +382,13 @@ dependencies = [ [[package]] name = "cairo-lang-debug" -version = "1.0.0-alpha.6" -source = "git+https://github.com/starkware-libs/cairo?rev=v1.0.0-alpha.6#439da05a031c2eda263c4ce12d0b71d20f38205f" +version = "1.0.0-alpha.7" +source = "git+https://github.com/starkware-libs/cairo?rev=7b4bbf3d57230e0e307fbb634394f6e57b3c63cc#7b4bbf3d57230e0e307fbb634394f6e57b3c63cc" [[package]] name = "cairo-lang-defs" -version = "1.0.0-alpha.6" -source = "git+https://github.com/starkware-libs/cairo?rev=v1.0.0-alpha.6#439da05a031c2eda263c4ce12d0b71d20f38205f" +version = "1.0.0-alpha.7" +source = "git+https://github.com/starkware-libs/cairo?rev=7b4bbf3d57230e0e307fbb634394f6e57b3c63cc#7b4bbf3d57230e0e307fbb634394f6e57b3c63cc" dependencies = [ "cairo-lang-debug", "cairo-lang-diagnostics", @@ -361,8 +404,8 @@ dependencies = [ [[package]] name = "cairo-lang-diagnostics" -version = "1.0.0-alpha.6" -source = "git+https://github.com/starkware-libs/cairo?rev=v1.0.0-alpha.6#439da05a031c2eda263c4ce12d0b71d20f38205f" +version = "1.0.0-alpha.7" +source = "git+https://github.com/starkware-libs/cairo?rev=7b4bbf3d57230e0e307fbb634394f6e57b3c63cc#7b4bbf3d57230e0e307fbb634394f6e57b3c63cc" dependencies = [ "cairo-lang-filesystem", "cairo-lang-utils", @@ -372,8 +415,8 @@ dependencies = [ [[package]] name = "cairo-lang-eq-solver" -version = "1.0.0-alpha.6" -source = "git+https://github.com/starkware-libs/cairo?rev=v1.0.0-alpha.6#439da05a031c2eda263c4ce12d0b71d20f38205f" +version = "1.0.0-alpha.7" +source = "git+https://github.com/starkware-libs/cairo?rev=7b4bbf3d57230e0e307fbb634394f6e57b3c63cc#7b4bbf3d57230e0e307fbb634394f6e57b3c63cc" dependencies = [ "cairo-lang-utils", "good_lp", @@ -383,20 +426,21 @@ dependencies = [ [[package]] name = "cairo-lang-filesystem" -version = "1.0.0-alpha.6" -source = "git+https://github.com/starkware-libs/cairo?rev=v1.0.0-alpha.6#439da05a031c2eda263c4ce12d0b71d20f38205f" +version = "1.0.0-alpha.7" +source = "git+https://github.com/starkware-libs/cairo?rev=7b4bbf3d57230e0e307fbb634394f6e57b3c63cc#7b4bbf3d57230e0e307fbb634394f6e57b3c63cc" dependencies = [ "cairo-lang-debug", "cairo-lang-utils", "path-clean", "salsa", + "serde", "smol_str", ] [[package]] name = "cairo-lang-lowering" -version = "1.0.0-alpha.6" -source = "git+https://github.com/starkware-libs/cairo?rev=v1.0.0-alpha.6#439da05a031c2eda263c4ce12d0b71d20f38205f" +version = "1.0.0-alpha.7" +source = "git+https://github.com/starkware-libs/cairo?rev=7b4bbf3d57230e0e307fbb634394f6e57b3c63cc#7b4bbf3d57230e0e307fbb634394f6e57b3c63cc" dependencies = [ "cairo-lang-debug", "cairo-lang-defs", @@ -419,8 +463,8 @@ dependencies = [ [[package]] name = "cairo-lang-parser" -version = "1.0.0-alpha.6" -source = "git+https://github.com/starkware-libs/cairo?rev=v1.0.0-alpha.6#439da05a031c2eda263c4ce12d0b71d20f38205f" +version = "1.0.0-alpha.7" +source = "git+https://github.com/starkware-libs/cairo?rev=7b4bbf3d57230e0e307fbb634394f6e57b3c63cc#7b4bbf3d57230e0e307fbb634394f6e57b3c63cc" dependencies = [ "cairo-lang-diagnostics", "cairo-lang-filesystem", @@ -430,14 +474,17 @@ dependencies = [ "colored", "itertools", "log", + "num-bigint", + "num-traits 0.2.15", "salsa", "smol_str", + "unescaper", ] [[package]] name = "cairo-lang-plugins" -version = "1.0.0-alpha.6" -source = "git+https://github.com/starkware-libs/cairo?rev=v1.0.0-alpha.6#439da05a031c2eda263c4ce12d0b71d20f38205f" +version = "1.0.0-alpha.7" +source = "git+https://github.com/starkware-libs/cairo?rev=7b4bbf3d57230e0e307fbb634394f6e57b3c63cc#7b4bbf3d57230e0e307fbb634394f6e57b3c63cc" dependencies = [ "cairo-lang-defs", "cairo-lang-diagnostics", @@ -448,15 +495,14 @@ dependencies = [ "cairo-lang-utils", "indoc", "itertools", - "pretty_assertions", "salsa", "smol_str", ] [[package]] name = "cairo-lang-proc-macros" -version = "1.0.0-alpha.6" -source = "git+https://github.com/starkware-libs/cairo?rev=v1.0.0-alpha.6#439da05a031c2eda263c4ce12d0b71d20f38205f" +version = "1.0.0-alpha.7" +source = "git+https://github.com/starkware-libs/cairo?rev=7b4bbf3d57230e0e307fbb634394f6e57b3c63cc#7b4bbf3d57230e0e307fbb634394f6e57b3c63cc" dependencies = [ "cairo-lang-debug", "quote", @@ -465,8 +511,8 @@ dependencies = [ [[package]] name = "cairo-lang-project" -version = "1.0.0-alpha.6" -source = "git+https://github.com/starkware-libs/cairo?rev=v1.0.0-alpha.6#439da05a031c2eda263c4ce12d0b71d20f38205f" +version = "1.0.0-alpha.7" +source = "git+https://github.com/starkware-libs/cairo?rev=7b4bbf3d57230e0e307fbb634394f6e57b3c63cc#7b4bbf3d57230e0e307fbb634394f6e57b3c63cc" dependencies = [ "cairo-lang-filesystem", "serde", @@ -477,8 +523,8 @@ dependencies = [ [[package]] name = "cairo-lang-runner" -version = "1.0.0-alpha.6" -source = "git+https://github.com/starkware-libs/cairo?rev=v1.0.0-alpha.6#439da05a031c2eda263c4ce12d0b71d20f38205f" +version = "1.0.0-alpha.7" +source = "git+https://github.com/starkware-libs/cairo?rev=7b4bbf3d57230e0e307fbb634394f6e57b3c63cc#7b4bbf3d57230e0e307fbb634394f6e57b3c63cc" dependencies = [ "anyhow", "ark-ff 0.4.2", @@ -494,9 +540,10 @@ dependencies = [ "cairo-lang-sierra-to-casm", "cairo-lang-utils", "cairo-vm", - "clap 4.1.13", + "clap", "itertools", "num-bigint", + "num-integer", "num-traits 0.2.15", "salsa", "thiserror", @@ -504,8 +551,8 @@ dependencies = [ [[package]] name = "cairo-lang-semantic" -version = "1.0.0-alpha.6" -source = "git+https://github.com/starkware-libs/cairo?rev=v1.0.0-alpha.6#439da05a031c2eda263c4ce12d0b71d20f38205f" +version = "1.0.0-alpha.7" +source = "git+https://github.com/starkware-libs/cairo?rev=7b4bbf3d57230e0e307fbb634394f6e57b3c63cc#7b4bbf3d57230e0e307fbb634394f6e57b3c63cc" dependencies = [ "cairo-lang-debug", "cairo-lang-defs", @@ -520,16 +567,14 @@ dependencies = [ "log", "num-bigint", "num-traits 0.2.15", - "pretty_assertions", "salsa", "smol_str", - "unescaper", ] [[package]] name = "cairo-lang-sierra" -version = "1.0.0-alpha.6" -source = "git+https://github.com/starkware-libs/cairo?rev=v1.0.0-alpha.6#439da05a031c2eda263c4ce12d0b71d20f38205f" +version = "1.0.0-alpha.7" +source = "git+https://github.com/starkware-libs/cairo?rev=7b4bbf3d57230e0e307fbb634394f6e57b3c63cc#7b4bbf3d57230e0e307fbb634394f6e57b3c63cc" dependencies = [ "cairo-lang-utils", "const-fnv1a-hash", @@ -550,8 +595,8 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-ap-change" -version = "1.0.0-alpha.6" -source = "git+https://github.com/starkware-libs/cairo?rev=v1.0.0-alpha.6#439da05a031c2eda263c4ce12d0b71d20f38205f" +version = "1.0.0-alpha.7" +source = "git+https://github.com/starkware-libs/cairo?rev=7b4bbf3d57230e0e307fbb634394f6e57b3c63cc#7b4bbf3d57230e0e307fbb634394f6e57b3c63cc" dependencies = [ "cairo-lang-eq-solver", "cairo-lang-sierra", @@ -562,8 +607,8 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-gas" -version = "1.0.0-alpha.6" -source = "git+https://github.com/starkware-libs/cairo?rev=v1.0.0-alpha.6#439da05a031c2eda263c4ce12d0b71d20f38205f" +version = "1.0.0-alpha.7" +source = "git+https://github.com/starkware-libs/cairo?rev=7b4bbf3d57230e0e307fbb634394f6e57b3c63cc#7b4bbf3d57230e0e307fbb634394f6e57b3c63cc" dependencies = [ "cairo-lang-eq-solver", "cairo-lang-sierra", @@ -574,8 +619,8 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-generator" -version = "1.0.0-alpha.6" -source = "git+https://github.com/starkware-libs/cairo?rev=v1.0.0-alpha.6#439da05a031c2eda263c4ce12d0b71d20f38205f" +version = "1.0.0-alpha.7" +source = "git+https://github.com/starkware-libs/cairo?rev=7b4bbf3d57230e0e307fbb634394f6e57b3c63cc#7b4bbf3d57230e0e307fbb634394f6e57b3c63cc" dependencies = [ "cairo-lang-debug", "cairo-lang-defs", @@ -599,8 +644,8 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-to-casm" -version = "1.0.0-alpha.6" -source = "git+https://github.com/starkware-libs/cairo?rev=v1.0.0-alpha.6#439da05a031c2eda263c4ce12d0b71d20f38205f" +version = "1.0.0-alpha.7" +source = "git+https://github.com/starkware-libs/cairo?rev=7b4bbf3d57230e0e307fbb634394f6e57b3c63cc#7b4bbf3d57230e0e307fbb634394f6e57b3c63cc" dependencies = [ "anyhow", "assert_matches", @@ -610,7 +655,7 @@ dependencies = [ "cairo-lang-sierra-ap-change", "cairo-lang-sierra-gas", "cairo-lang-utils", - "clap 4.1.13", + "clap", "indoc", "itertools", "log", @@ -621,8 +666,8 @@ dependencies = [ [[package]] name = "cairo-lang-starknet" -version = "1.0.0-alpha.6" -source = "git+https://github.com/starkware-libs/cairo?rev=v1.0.0-alpha.6#439da05a031c2eda263c4ce12d0b71d20f38205f" +version = "1.0.0-alpha.7" +source = "git+https://github.com/starkware-libs/cairo?rev=7b4bbf3d57230e0e307fbb634394f6e57b3c63cc#7b4bbf3d57230e0e307fbb634394f6e57b3c63cc" dependencies = [ "anyhow", "cairo-lang-casm", @@ -641,16 +686,16 @@ dependencies = [ "cairo-lang-sierra-to-casm", "cairo-lang-syntax", "cairo-lang-utils", - "clap 4.1.13", + "clap", "convert_case", "genco", "indoc", "itertools", - "lazy_static", "log", "num-bigint", "num-integer", "num-traits 0.2.15", + "once_cell", "serde", "serde_json", "sha3", @@ -660,20 +705,24 @@ dependencies = [ [[package]] name = "cairo-lang-syntax" -version = "1.0.0-alpha.6" -source = "git+https://github.com/starkware-libs/cairo?rev=v1.0.0-alpha.6#439da05a031c2eda263c4ce12d0b71d20f38205f" +version = "1.0.0-alpha.7" +source = "git+https://github.com/starkware-libs/cairo?rev=7b4bbf3d57230e0e307fbb634394f6e57b3c63cc#7b4bbf3d57230e0e307fbb634394f6e57b3c63cc" dependencies = [ "cairo-lang-debug", "cairo-lang-filesystem", "cairo-lang-utils", + "num-bigint", + "num-traits 0.2.15", "salsa", "smol_str", + "thiserror", + "unescaper", ] [[package]] name = "cairo-lang-syntax-codegen" -version = "1.0.0-alpha.6" -source = "git+https://github.com/starkware-libs/cairo?rev=v1.0.0-alpha.6#439da05a031c2eda263c4ce12d0b71d20f38205f" +version = "1.0.0-alpha.7" +source = "git+https://github.com/starkware-libs/cairo?rev=7b4bbf3d57230e0e307fbb634394f6e57b3c63cc#7b4bbf3d57230e0e307fbb634394f6e57b3c63cc" dependencies = [ "cairo-lang-utils", "genco", @@ -683,10 +732,9 @@ dependencies = [ [[package]] name = "cairo-lang-utils" -version = "1.0.0-alpha.6" -source = "git+https://github.com/starkware-libs/cairo?rev=v1.0.0-alpha.6#439da05a031c2eda263c4ce12d0b71d20f38205f" +version = "1.0.0-alpha.7" +source = "git+https://github.com/starkware-libs/cairo?rev=7b4bbf3d57230e0e307fbb634394f6e57b3c63cc#7b4bbf3d57230e0e307fbb634394f6e57b3c63cc" dependencies = [ - "chrono", "env_logger", "indexmap", "itertools", @@ -695,18 +743,31 @@ dependencies = [ "num-integer", "num-traits 0.2.15", "serde", + "time", +] + +[[package]] +name = "cairo-take_until_unbalanced" +version = "0.24.2-rc1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4e174056df7cfe9b579376f32de405722e1090c74deb2540bb0cd9e7931772d" +dependencies = [ + "nom", ] [[package]] name = "cairo-vm" -version = "0.1.3" +version = "0.3.0-rc1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcebc4cad4c0ccd838f8a857fcc61df9fc4cb7c855b4a04f7b71b9566b4cb940" +checksum = "9f4af8c3e7be5ac46b7da4a3ab551ee4c8c8e2fdb501a4dda4dceef4c66dbcde" dependencies = [ + "anyhow", "bincode", + "bitvec", "cairo-felt", - "clap 3.2.23", + "cairo-take_until_unbalanced", "generic-array", + "hashbrown 0.13.2", "hex", "keccak", "lazy_static", @@ -715,15 +776,15 @@ dependencies = [ "num-bigint", "num-integer", "num-traits 0.2.15", - "parse-hyperlinks", "rand_core", "serde", "serde_bytes", "serde_json", - "sha2 0.10.6", + "sha2", "sha3", "starknet-crypto", "thiserror", + "thiserror-no-std", ] [[package]] @@ -744,105 +805,53 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "chrono" -version = "0.4.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" -dependencies = [ - "iana-time-zone", - "js-sys", - "num-integer", - "num-traits 0.2.15", - "time", - "wasm-bindgen", - "winapi 0.3.9", -] - [[package]] name = "clap" -version = "3.2.23" +version = "4.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5" +checksum = "9b802d85aaf3a1cdb02b224ba472ebdea62014fccfcb269b95a4d76443b5ee5a" dependencies = [ - "atty", - "bitflags", - "clap_derive 3.2.18", - "clap_lex 0.2.4", - "indexmap", + "clap_builder", + "clap_derive", "once_cell", - "strsim", - "termcolor", - "textwrap", ] [[package]] -name = "clap" -version = "4.1.13" +name = "clap_builder" +version = "4.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c911b090850d79fc64fe9ea01e28e465f65e821e08813ced95bced72f7a8a9b" +checksum = "14a1a858f532119338887a4b8e1af9c60de8249cd7bafd68036a489e261e37b6" dependencies = [ + "anstream", + "anstyle", "bitflags", - "clap_derive 4.1.12", - "clap_lex 0.3.3", - "is-terminal", - "once_cell", + "clap_lex", "strsim", - "termcolor", -] - -[[package]] -name = "clap_derive" -version = "3.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65" -dependencies = [ - "heck 0.4.1", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.109", ] [[package]] name = "clap_derive" -version = "4.1.12" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a932373bab67b984c790ddf2c9ca295d8e3af3b7ef92de5a5bacdccdee4b09b" +checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4" dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.8", -] - -[[package]] -name = "clap_lex" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" -dependencies = [ - "os_str_bytes", + "syn 2.0.15", ] [[package]] name = "clap_lex" -version = "0.3.3" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "033f6b7a4acb1f358c742aaca805c939ee73b4c6209ae4318ec7aca81c42e646" -dependencies = [ - "os_str_bytes", -] +checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" [[package]] -name = "codespan-reporting" -version = "0.11.1" +name = "colorchoice" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" -dependencies = [ - "termcolor", - "unicode-width", -] +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "colored" @@ -883,26 +892,20 @@ dependencies = [ "unicode-segmentation", ] -[[package]] -name = "core-foundation-sys" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" - [[package]] name = "cpufeatures" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181" dependencies = [ "libc", ] [[package]] name = "crossbeam-channel" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf2b3e8478797446514c91ef04bafcb59faba183e621ad488df88983cc14128c" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" dependencies = [ "cfg-if 1.0.0", "crossbeam-utils", @@ -949,12 +952,11 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-bigint" -version = "0.3.2" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" dependencies = [ "generic-array", - "rand_core", "subtle", "zeroize", ] @@ -969,70 +971,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "crypto-mac" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" -dependencies = [ - "generic-array", - "subtle", -] - -[[package]] -name = "ctor" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" -dependencies = [ - "quote", - "syn 1.0.109", -] - -[[package]] -name = "cxx" -version = "1.0.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9c00419335c41018365ddf7e4d5f1c12ee3659ddcf3e01974650ba1de73d038" -dependencies = [ - "cc", - "cxxbridge-flags", - "cxxbridge-macro", - "link-cplusplus", -] - -[[package]] -name = "cxx-build" -version = "1.0.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb8307ad413a98fff033c8545ecf133e3257747b3bae935e7602aab8aa92d4ca" -dependencies = [ - "cc", - "codespan-reporting", - "once_cell", - "proc-macro2", - "quote", - "scratch", - "syn 2.0.8", -] - -[[package]] -name = "cxxbridge-flags" -version = "1.0.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edc52e2eb08915cb12596d29d55f0b5384f00d697a646dbd269b6ecb0fbd9d31" - -[[package]] -name = "cxxbridge-macro" -version = "1.0.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "631569015d0d8d54e6c241733f944042623ab6df7bc3be7466874b05fcdb1c5f" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.8", -] - [[package]] name = "derivative" version = "2.2.0" @@ -1071,8 +1009,9 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ - "block-buffer 0.10.4", + "block-buffer", "crypto-common", + "subtle", ] [[package]] @@ -1132,13 +1071,13 @@ dependencies = [ [[package]] name = "errno" -version = "0.2.8" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ "errno-dragonfly", "libc", - "winapi 0.3.9", + "windows-sys 0.48.0", ] [[package]] @@ -1165,14 +1104,14 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a3de6e8d11b22ff9edc6d916f890800597d60f8b2da1caf2955c274638d6412" +checksum = "5cbc844cecaee9d4443931972e1289c8ff485cb4cc2767cb03ca139ed6885153" dependencies = [ "cfg-if 1.0.0", "libc", "redox_syscall", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -1231,6 +1170,12 @@ 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 = "genco" version = "0.17.5" @@ -1255,9 +1200,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", @@ -1265,14 +1210,14 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" dependencies = [ "cfg-if 1.0.0", "js-sys", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "wasm-bindgen", ] @@ -1298,6 +1243,16 @@ 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", + "serde", +] + [[package]] name = "heck" version = "0.3.3" @@ -1345,12 +1300,11 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hmac" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "crypto-mac", - "digest 0.9.0", + "digest 0.10.6", ] [[package]] @@ -1362,45 +1316,12 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "html-escape" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d1ad449764d627e22bfd7cd5e8868264fc9236e07c752972b4080cd351cb476" -dependencies = [ - "utf8-width", -] - [[package]] name = "humantime" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" -[[package]] -name = "iana-time-zone" -version = "0.1.54" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c17cc76786e99f8d2f055c11159e7f0091c42474dcc3189fbab96072e873e6d" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" -dependencies = [ - "cxx", - "cxx-build", -] - [[package]] name = "id-arena" version = "2.2.1" @@ -1409,12 +1330,13 @@ checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" [[package]] name = "indexmap" -version = "1.9.2" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.12.3", + "serde", ] [[package]] @@ -1431,9 +1353,9 @@ dependencies = [ [[package]] name = "indoc" -version = "1.0.9" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa799dd5ed20a7e349f3b4639aa80d74549c81716d9ec4f994c9b5815598306" +checksum = "9f2cb48b81b1dc9f39676bf99f5499babfec7cd8fe14307f7b3d747208fb5690" [[package]] name = "inotify" @@ -1466,13 +1388,13 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09270fd4fa1111bc614ed2246c7ef56239a3063d5be0d1ec3b589c505d400aeb" +checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" dependencies = [ "hermit-abi 0.3.1", "libc", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -1486,14 +1408,14 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.5" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8687c819457e979cc940d09cb16e42a1bf70aa6b60a549de6d3a62a0ee90c69e" +checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" dependencies = [ "hermit-abi 0.3.1", "io-lifetimes", "rustix", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -1541,15 +1463,15 @@ dependencies = [ [[package]] name = "lalrpop" -version = "0.19.8" +version = "0.19.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b30455341b0e18f276fa64540aff54deafb54c589de6aca68659c63dd2d5d823" +checksum = "f34313ec00c2eb5c3c87ca6732ea02dcf3af99c3ff7a8fb622ffb99c9d860a87" dependencies = [ "ascii-canvas", - "atty", "bit-set", "diff", "ena", + "is-terminal", "itertools", "lalrpop-util", "petgraph", @@ -1564,9 +1486,9 @@ dependencies = [ [[package]] name = "lalrpop-util" -version = "0.19.8" +version = "0.19.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf796c978e9b4d983414f4caedc9273aa33ee214c5b887bd55fde84c85d2dc4" +checksum = "e5c1f7869c94d214466c5fd432dfed12c379fd87786768d36455892d46b18edd" dependencies = [ "regex", ] @@ -1576,6 +1498,9 @@ name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin", +] [[package]] name = "lazycell" @@ -1585,34 +1510,25 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.140" +version = "0.2.141" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" +checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" [[package]] name = "libmimalloc-sys" -version = "0.1.30" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8c7cbf8b89019683667e347572e6d55a7df7ea36b0c4ce69961b0cde67b174" +checksum = "43a558e3d911bc3c7bfc8c78bc580b404d6e51c1cefbf656e176a94b49b0df40" dependencies = [ "cc", "libc", ] -[[package]] -name = "link-cplusplus" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" -dependencies = [ - "cc", -] - [[package]] name = "linux-raw-sys" -version = "0.1.4" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" +checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f" [[package]] name = "lock_api" @@ -1659,9 +1575,9 @@ dependencies = [ [[package]] name = "mimalloc" -version = "0.1.34" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dcb174b18635f7561a0c6c9fc2ce57218ac7523cf72c50af80e2d79ab8f3ba1" +checksum = "3d88dad3f985ec267a3fcb7a1726f5cb1a7e8cad8b646e70a84f967210df23da" dependencies = [ "libmimalloc-sys", ] @@ -1849,6 +1765,15 @@ dependencies = [ "libc", ] +[[package]] +name = "num_threads" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +dependencies = [ + "libc", +] + [[package]] name = "number_prefix" version = "0.4.0" @@ -1867,27 +1792,6 @@ version = "11.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "os_str_bytes" -version = "6.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267" - -[[package]] -name = "output_vt100" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "628223faebab4e3e40667ee0b2336d34a5b960ff60ea743ddfdbcf7770bcfb66" -dependencies = [ - "winapi 0.3.9", -] - [[package]] name = "parking_lot" version = "0.11.2" @@ -1936,18 +1840,6 @@ dependencies = [ "windows-sys 0.45.0", ] -[[package]] -name = "parse-hyperlinks" -version = "0.23.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0181d37c4d5ae35cc8be7cf823c1a933005661da6a08bcb2855aa392c9a54b8e" -dependencies = [ - "html-escape", - "nom", - "percent-encoding", - "thiserror", -] - [[package]] name = "paste" version = "1.0.12" @@ -1960,17 +1852,11 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ecba01bf2678719532c5e3059e0b5f0811273d94b397088b82e3bd0a78c78fdd" -[[package]] -name = "percent-encoding" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" - [[package]] name = "pest" -version = "2.5.6" +version = "2.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cbd939b234e95d72bc393d51788aec68aeeb5d51e748ca08ff3aad58cb722f7" +checksum = "7b1403e8401ad5dedea73c626b99758535b342502f8d1e361f4a2dd952749122" dependencies = [ "thiserror", "ucd-trie", @@ -2042,47 +1928,11 @@ dependencies = [ "termtree", ] -[[package]] -name = "pretty_assertions" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a25e9bcb20aa780fd0bb16b72403a9064d6b3f22f026946029acb941a50af755" -dependencies = [ - "ctor", - "diff", - "output_vt100", - "yansi", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name = "proc-macro2" -version = "1.0.53" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba466839c78239c09faf015484e5cc04860f88242cff4d03eb038f04b4699b73" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" dependencies = [ "unicode-ident", ] @@ -2096,6 +1946,12 @@ dependencies = [ "proc-macro2", ] +[[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" @@ -2121,9 +1977,6 @@ name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] [[package]] name = "rawpointer" @@ -2175,9 +2028,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.7.2" +version = "1.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cce168fea28d3e05f158bda4576cf0c844d5045bc2cc3620fa0292ed5bb5814c" +checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d" dependencies = [ "aho-corasick", "memchr", @@ -2198,9 +2051,9 @@ checksum = "4bf2521270932c3c7bed1a59151222bd7643c79310f2916f01925e1e16255698" [[package]] name = "rfc6979" -version = "0.1.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96ef608575f6392792f9ecf7890c00086591d29a83910939d430753f7c050525" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" dependencies = [ "crypto-bigint", "hmac", @@ -2233,16 +2086,16 @@ dependencies = [ [[package]] name = "rustix" -version = "0.36.11" +version = "0.37.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db4165c9963ab29e422d6c26fbc1d37f15bace6b2810221f9d925023480fcf0e" +checksum = "85597d61f83914ddeba6a47b3b8ffe7365107221c2e557ed94426489fefb5f77" dependencies = [ "bitflags", "errno", "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -2301,12 +2154,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" -[[package]] -name = "scratch" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" - [[package]] name = "semver" version = "0.11.0" @@ -2333,9 +2180,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.158" +version = "1.0.160" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "771d4d9c4163ee138805e12c710dd365e4f44be8be0503cb1bb9eb989425d9c9" +checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c" dependencies = [ "serde_derive", ] @@ -2351,39 +2198,26 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.158" +version = "1.0.160" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e801c1712f48475582b7696ac71e0ca34ebb30e09338425384269d9717c62cad" +checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df" dependencies = [ "proc-macro2", "quote", - "syn 2.0.8", + "syn 2.0.15", ] [[package]] name = "serde_json" -version = "1.0.94" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea" +checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" dependencies = [ "itoa", "ryu", "serde", ] -[[package]] -name = "sha2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if 1.0.0", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", -] - [[package]] name = "sha2" version = "0.10.6" @@ -2397,9 +2231,9 @@ dependencies = [ [[package]] name = "sha3" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdf0c33fae925bdc080598b84bc15c55e7b9a4a43b3c704da051f977469691c9" +checksum = "54c2bb1a323307527314a36bfb73f24febb08ce2b8a554bf4ffd6f51ad15198c" dependencies = [ "digest 0.10.6", "keccak", @@ -2428,13 +2262,19 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "smol_str" -version = "0.1.24" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fad6c857cbab2627dcf01ec85a623ca4e7dcb5691cbaa3d7fb7653671f0d09c9" +checksum = "74212e6bbe9a4352329b2f68ba3130c15a3f26fe88ff22dbdc6cdd58fa85e99c" dependencies = [ "serde", ] +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + [[package]] name = "sprs" version = "0.7.1" @@ -2462,6 +2302,7 @@ dependencies = [ "cairo-lang-defs", "cairo-lang-diagnostics", "cairo-lang-filesystem", + "cairo-lang-lowering", "cairo-lang-plugins", "cairo-lang-runner", "cairo-lang-semantic", @@ -2474,7 +2315,7 @@ dependencies = [ "cairo-lang-syntax", "cairo-lang-utils", "cairo-vm", - "clap 4.1.13", + "clap", "colored", "console", "glob", @@ -2492,13 +2333,14 @@ dependencies = [ "serde_json", "thiserror", "toml 0.5.11", + "unescaper", ] [[package]] name = "starknet-crypto" -version = "0.2.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be7d6b2c959fde2a10dbc31d54bdd0307eecb7ef6c05c23a0263e65b57b3e18a" +checksum = "d49eb65d58fa98a164ad2cd4d04775885386b83bdad6060f168a38ede77c9aed" dependencies = [ "crypto-bigint", "hex", @@ -2507,19 +2349,18 @@ dependencies = [ "num-integer", "num-traits 0.2.15", "rfc6979", - "sha2 0.9.9", + "sha2", "starknet-crypto-codegen", "starknet-curve", "starknet-ff", - "thiserror", "zeroize", ] [[package]] name = "starknet-crypto-codegen" -version = "0.1.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6569d70430f0f6edc41f6820d00acf63356e6308046ca01e57eeac22ad258c47" +checksum = "bff08f74f3ac785ac34ac05c68c5bd4df280107ab35df69dbcbde35183d89eba" dependencies = [ "starknet-curve", "starknet-ff", @@ -2528,27 +2369,23 @@ dependencies = [ [[package]] name = "starknet-curve" -version = "0.1.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84be6079d3060fdbd8b5335574fef3d3783fa2f7ee6474d08ae0c1e4b0a29ba4" +checksum = "fe0dbde7ef14d54c2117bc6d2efb68c2383005f1cd749b277c11df874d07b7af" dependencies = [ "starknet-ff", ] [[package]] name = "starknet-ff" -version = "0.2.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5874510620214ebeac50915b01d67437d8ca10a6682b1de85b93cd01157b58eb" +checksum = "78d484109da192f3a8cd58f674861c2d5e4b3e1765a466362c6f350ef213dfd1" dependencies = [ "ark-ff 0.3.0", - "bigdecimal", "crypto-bigint", "getrandom", "hex", - "num-bigint", - "serde", - "thiserror", ] [[package]] @@ -2589,9 +2426,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.8" +version = "2.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcc02725fd69ab9f26eab07fad303e2497fad6fb9eba4f96c4d1687bdf704ad9" +checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" dependencies = [ "proc-macro2", "quote", @@ -2599,16 +2436,10 @@ dependencies = [ ] [[package]] -name = "synstructure" -version = "0.12.6" +name = "tap" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", - "unicode-xid", -] +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "term" @@ -2636,12 +2467,6 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" -[[package]] -name = "textwrap" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" - [[package]] name = "thiserror" version = "1.0.40" @@ -2659,18 +2484,56 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.8", + "syn 2.0.15", +] + +[[package]] +name = "thiserror-impl-no-std" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58e6318948b519ba6dc2b442a6d0b904ebfb8d411a3ad3e07843615a72249758" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "thiserror-no-std" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3ad459d94dd517257cc96add8a43190ee620011bb6e6cdc82dafd97dfafafea" +dependencies = [ + "thiserror-impl-no-std", ] [[package]] name = "time" -version = "0.1.45" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" +checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890" dependencies = [ + "itoa", "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi 0.3.9", + "num_threads", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" + +[[package]] +name = "time-macros" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd80a657e71da814b8e5d60d3374fc6d35045062245d80224748ae522dd76f36" +dependencies = [ + "time-core", ] [[package]] @@ -2746,10 +2609,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] -name = "utf8-width" -version = "0.1.6" +name = "utf8parse" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5190c9442dcdaf0ddd50f37420417d219ae5261bbf5db120d0f9bab996c9cba1" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "version_check" @@ -2767,12 +2630,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -2877,36 +2734,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "windows" -version = "0.46.0" +name = "windows-sys" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdacb41e6a96a052c6cb63a144f24900236121c6f63f4f8219fef5977ecb0c25" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ - "windows-targets", + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", ] [[package]] name = "windows-sys" -version = "0.42.0" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows-targets 0.42.2", ] [[package]] name = "windows-sys" -version = "0.45.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.0", ] [[package]] @@ -2915,13 +2772,28 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", ] [[package]] @@ -2930,42 +2802,84 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + [[package]] name = "windows_i686_gnu" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + [[package]] name = "windows_i686_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + [[package]] name = "ws2_32-sys" version = "0.2.1" @@ -2976,6 +2890,15 @@ 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 = "xshell" version = "0.2.3" @@ -2991,29 +2914,22 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dbabb1cbd15a1d6d12d9ed6b35cc6777d4af87ab3ba155ea37215f20beab80c" -[[package]] -name = "yansi" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" - [[package]] name = "zeroize" -version = "1.5.7" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" dependencies = [ "zeroize_derive", ] [[package]] name = "zeroize_derive" -version = "1.3.3" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44bf07cb3e50ea2003396695d58bf46bc9887a1f362260446fad6bc4e79bd36c" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", - "synstructure", + "syn 2.0.15", ] diff --git a/Cargo.toml b/Cargo.toml index 48876d911..8d822b6df 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,30 +23,31 @@ home = "0.5.3" glob = "0.3.0" # Cairo runner dependencies -cairo-lang-runner = { git = "https://github.com/starkware-libs/cairo",rev = "v1.0.0-alpha.6"} -cairo-lang-compiler = { git = "https://github.com/starkware-libs/cairo",rev = "v1.0.0-alpha.6"} -cairo-lang-casm = { git = "https://github.com/starkware-libs/cairo",rev = "v1.0.0-alpha.6"} -cairo-lang-diagnostics = { git = "https://github.com/starkware-libs/cairo",rev = "v1.0.0-alpha.6"} -cairo-lang-debug = { git = "https://github.com/starkware-libs/cairo",rev = "v1.0.0-alpha.6"} -cairo-lang-defs = { git = "https://github.com/starkware-libs/cairo",rev = "v1.0.0-alpha.6"} -cairo-lang-sierra = { git = "https://github.com/starkware-libs/cairo",rev = "v1.0.0-alpha.6"} -cairo-lang-sierra-ap-change = { git = "https://github.com/starkware-libs/cairo",rev = "v1.0.0-alpha.6"} -cairo-lang-sierra-gas = { git = "https://github.com/starkware-libs/cairo",rev = "v1.0.0-alpha.6"} -cairo-lang-sierra-generator = { git = "https://github.com/starkware-libs/cairo",rev = "v1.0.0-alpha.6"} -cairo-lang-semantic = { git = "https://github.com/starkware-libs/cairo",rev = "v1.0.0-alpha.6"} -cairo-lang-sierra-to-casm = { git = "https://github.com/starkware-libs/cairo",rev = "v1.0.0-alpha.6"} -cairo-lang-utils = { git = "https://github.com/starkware-libs/cairo",rev = "v1.0.0-alpha.6"} -cairo-lang-filesystem = { git = "https://github.com/starkware-libs/cairo",rev = "v1.0.0-alpha.6"} -cairo-lang-starknet = { git = "https://github.com/starkware-libs/cairo",rev = "v1.0.0-alpha.6"} -cairo-lang-syntax = { git = "https://github.com/starkware-libs/cairo",rev = "v1.0.0-alpha.6"} -cairo-lang-plugins = { git = "https://github.com/starkware-libs/cairo",rev = "v1.0.0-alpha.6"} +cairo-lang-runner = { git = "https://github.com/starkware-libs/cairo",rev = "7b4bbf3d57230e0e307fbb634394f6e57b3c63cc"} +cairo-lang-compiler = { git = "https://github.com/starkware-libs/cairo",rev = "7b4bbf3d57230e0e307fbb634394f6e57b3c63cc"} +cairo-lang-casm = { git = "https://github.com/starkware-libs/cairo",rev = "7b4bbf3d57230e0e307fbb634394f6e57b3c63cc"} +cairo-lang-diagnostics = { git = "https://github.com/starkware-libs/cairo",rev = "7b4bbf3d57230e0e307fbb634394f6e57b3c63cc"} +cairo-lang-debug = { git = "https://github.com/starkware-libs/cairo",rev = "7b4bbf3d57230e0e307fbb634394f6e57b3c63cc"} +cairo-lang-defs = { git = "https://github.com/starkware-libs/cairo",rev = "7b4bbf3d57230e0e307fbb634394f6e57b3c63cc"} +cairo-lang-sierra = { git = "https://github.com/starkware-libs/cairo",rev = "7b4bbf3d57230e0e307fbb634394f6e57b3c63cc"} +cairo-lang-sierra-ap-change = { git = "https://github.com/starkware-libs/cairo",rev = "7b4bbf3d57230e0e307fbb634394f6e57b3c63cc"} +cairo-lang-sierra-gas = { git = "https://github.com/starkware-libs/cairo",rev = "7b4bbf3d57230e0e307fbb634394f6e57b3c63cc"} +cairo-lang-sierra-generator = { git = "https://github.com/starkware-libs/cairo",rev = "7b4bbf3d57230e0e307fbb634394f6e57b3c63cc"} +cairo-lang-semantic = { git = "https://github.com/starkware-libs/cairo",rev = "7b4bbf3d57230e0e307fbb634394f6e57b3c63cc"} +cairo-lang-sierra-to-casm = { git = "https://github.com/starkware-libs/cairo",rev = "7b4bbf3d57230e0e307fbb634394f6e57b3c63cc"} +cairo-lang-utils = { git = "https://github.com/starkware-libs/cairo",rev = "7b4bbf3d57230e0e307fbb634394f6e57b3c63cc"} +cairo-lang-filesystem = { git = "https://github.com/starkware-libs/cairo",rev = "7b4bbf3d57230e0e307fbb634394f6e57b3c63cc"} +cairo-lang-starknet = { git = "https://github.com/starkware-libs/cairo",rev = "7b4bbf3d57230e0e307fbb634394f6e57b3c63cc"} +cairo-lang-syntax = { git = "https://github.com/starkware-libs/cairo",rev = "7b4bbf3d57230e0e307fbb634394f6e57b3c63cc"} +cairo-lang-plugins = { git = "https://github.com/starkware-libs/cairo",rev = "7b4bbf3d57230e0e307fbb634394f6e57b3c63cc"} +cairo-lang-lowering = { git = "https://github.com/starkware-libs/cairo",rev = "7b4bbf3d57230e0e307fbb634394f6e57b3c63cc"} anyhow = "1.0.66" ark-ff = "0.4.0-alpha.7" ark-std = "0.3.0" -cairo-felt = "0.1.1" -cairo-vm = "0.1.1" +cairo-felt = "0.3.0-rc1" +cairo-vm = "0.3.0-rc1" clap = { version = "4.0", features = ["derive"] } itertools = "0.10.3" num-bigint = "0.4" @@ -55,6 +56,7 @@ salsa = "0.16.1" thiserror = "1.0.32" rayon = "0.9.0" colored = "2" +unescaper = "0.1.1" [dev-dependencies] assert_cmd = "0.11.0" diff --git a/corelib/Scarb.toml b/corelib/Scarb.toml index 55463ed7b..205d1be79 100644 --- a/corelib/Scarb.toml +++ b/corelib/Scarb.toml @@ -1,6 +1,6 @@ [package] name = "core" -version = "1.0.0-alpha.6" +version = "1.0.0-alpha.7" # 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. diff --git a/corelib/src/array.cairo b/corelib/src/array.cairo index f7924d9b3..ae9803d49 100644 --- a/corelib/src/array.cairo +++ b/corelib/src/array.cairo @@ -1,28 +1,35 @@ -use gas::withdraw_gas; +use traits::IndexView; + use box::BoxTrait; +use gas::withdraw_gas; +use option::OptionTrait; 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_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; trait ArrayTrait { fn new() -> Array; fn append(ref self: Array, value: T); - fn pop_front(ref self: Array) -> Option; + fn pop_front(ref self: Array) -> Option nopanic; fn get(self: @Array, index: usize) -> Option>; fn at(self: @Array, index: usize) -> @T; fn len(self: @Array) -> usize; fn is_empty(self: @Array) -> bool; fn span(self: @Array) -> Span; } -impl ArrayImpl of ArrayTrait:: { +impl ArrayImpl of ArrayTrait { #[inline(always)] fn new() -> Array { array_new() @@ -32,7 +39,7 @@ impl ArrayImpl of ArrayTrait:: { array_append(ref self, value) } #[inline(always)] - fn pop_front(ref self: Array) -> Option { + 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(()), @@ -60,26 +67,33 @@ impl ArrayImpl of ArrayTrait:: { } } -// Impls for common generic types -impl ArrayDrop> of Drop::>; +impl ArrayIndex of IndexView, usize, @T> { + fn index(self: @Array, index: usize) -> @T { + array_at(self, index).unbox() + } +} +// Impls for common generic types +impl ArrayDrop> of Drop>; // Span. struct Span { snapshot: @Array } -impl SpanCopy of Copy::>; -impl SpanDrop of Drop::>; +impl SpanCopy of Copy>; +impl SpanDrop of Drop>; trait SpanTrait { fn pop_front(ref self: Span) -> Option<@T>; + fn pop_back(ref self: Span) -> Option<@T>; fn get(self: Span, index: usize) -> Option>; fn at(self: Span, index: usize) -> @T; + fn slice(self: Span, start: usize, length: usize) -> Span; fn len(self: Span) -> usize; fn is_empty(self: Span) -> bool; } -impl SpanImpl of SpanTrait:: { +impl SpanImpl of SpanTrait { #[inline(always)] fn pop_front(ref self: Span) -> Option<@T> { let mut snapshot = self.snapshot; @@ -91,6 +105,17 @@ impl SpanImpl of SpanTrait:: { } } + #[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) @@ -100,6 +125,10 @@ impl SpanImpl of SpanTrait:: { 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)] fn len(self: Span) -> usize { array_len(self.snapshot) } @@ -109,31 +138,28 @@ impl SpanImpl of SpanTrait:: { } } -impl ArrayTCloneImpl, impl TDrop: Drop::> of Clone::> { - fn clone(self: @Array) -> Array { - let mut response = array_new(); - clone_loop(self.span(), ref response); - response +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. -fn clone_loop, impl TDrop: Drop::>( - mut span: Span, ref response: Array -) { - match withdraw_gas() { - Option::Some(_) => {}, - Option::None(_) => { - let mut data = array_new(); - array_append(ref data, 'Out of gas'); - panic(data); - }, - } - match span.pop_front() { - Option::Some(v) => { - response.append(TClone::clone(v)); - clone_loop(span, ref response); - }, - Option::None(_) => {}, +impl ArrayTCloneImpl, impl TDrop: 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(TClone::clone(v)); + }, + Option::None(_) => { + break (); + }, + }; + }; + response } } diff --git a/corelib/src/box.cairo b/corelib/src/box.cairo index 5096f6307..7887fb3d6 100644 --- a/corelib/src/box.cairo +++ b/corelib/src/box.cairo @@ -1,6 +1,6 @@ extern type Box; -impl BoxTCopy> of Copy::>; -impl BoxTDrop> of Drop::>; +impl BoxTCopy> of Copy>; +impl BoxTDrop> of Drop>; // 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. @@ -9,17 +9,17 @@ extern fn into_box(value: T) -> Box nopanic; extern fn unbox(box: Box) -> T nopanic; trait BoxTrait { - fn new(value: T) -> Box; - fn unbox(self: Box) -> T; + fn new(value: T) -> Box nopanic; + fn unbox(self: Box) -> T nopanic; } -impl BoxImpl of BoxTrait:: { +impl BoxImpl of BoxTrait { #[inline(always)] - fn new(value: T) -> Box { + fn new(value: T) -> Box nopanic { into_box(value) } #[inline(always)] - fn unbox(self: Box) -> T { + fn unbox(self: Box) -> T nopanic { unbox(self) } } diff --git a/corelib/src/clone.cairo b/corelib/src/clone.cairo index 0ffe50751..fc71f2017 100644 --- a/corelib/src/clone.cairo +++ b/corelib/src/clone.cairo @@ -2,7 +2,7 @@ trait Clone { fn clone(self: @T) -> T; } -impl TCopyClone> of Clone:: { +impl TCopyClone> of Clone { fn clone(self: @T) -> T { *self } diff --git a/corelib/src/debug.cairo b/corelib/src/debug.cairo index dbf22c70c..f2e63d616 100644 --- a/corelib/src/debug.cairo +++ b/corelib/src/debug.cairo @@ -1,6 +1,5 @@ use array::ArrayTrait; use traits::Into; -use starknet::ContractAddressIntoFelt252; use option::Option; // Usage: @@ -31,13 +30,13 @@ trait PrintTrait { fn print(self: T); } -impl Felt252PrintImpl of PrintTrait:: { +impl Felt252PrintImpl of PrintTrait { fn print(self: felt252) { print_felt252(self); } } -impl BoolPrintImpl of PrintTrait:: { +impl BoolPrintImpl of PrintTrait { fn print(self: bool) { if self { 'true'.print(); @@ -47,45 +46,51 @@ impl BoolPrintImpl of PrintTrait:: { } } -impl ContractAddressPrintImpl of PrintTrait:: { +impl ContractAddressPrintImpl of PrintTrait { fn print(self: starknet::ContractAddress) { - self.into().print(); + Into::<_, felt252>::into(self).print(); } } -impl U8PrintImpl of PrintTrait:: { +impl U8PrintImpl of PrintTrait { fn print(self: u8) { - self.into().print(); + Into::<_, felt252>::into(self).print(); } } -impl U32PrintImpl of PrintTrait:: { +impl U16PrintImpl of PrintTrait { + fn print(self: u16) { + Into::<_, felt252>::into(self).print(); + } +} + +impl U32PrintImpl of PrintTrait { fn print(self: u32) { - self.into().print(); + Into::<_, felt252>::into(self).print(); } } -impl U64PrintImpl of PrintTrait:: { +impl U64PrintImpl of PrintTrait { fn print(self: u64) { - self.into().print(); + Into::<_, felt252>::into(self).print(); } } -impl U128PrintImpl of PrintTrait:: { +impl U128PrintImpl of PrintTrait { fn print(self: u128) { - self.into().print(); + Into::<_, felt252>::into(self).print(); } } -impl U256PrintImpl of PrintTrait:: { +impl U256PrintImpl of PrintTrait { fn print(self: u256) { self.low.into().print(); self.high.into().print(); } } -impl ArrayGenericPrintImpl of PrintTrait::> { - fn print(mut self: Array::) { +impl ArrayGenericPrintImpl of PrintTrait> { + fn print(mut self: Array) { print(self); } } diff --git a/corelib/src/dict.cairo b/corelib/src/dict.cairo index df73a0bd1..0bce13a37 100644 --- a/corelib/src/dict.cairo +++ b/corelib/src/dict.cairo @@ -1,6 +1,8 @@ +use traits::Index; + extern type Felt252Dict; extern type SquashedFelt252Dict; -impl SquashedFelt252DictDrop> of Drop::>; +impl SquashedFelt252DictDrop> of Drop>; extern fn felt252_dict_new() -> Felt252Dict implicits(SegmentArena) nopanic; extern fn felt252_dict_write(ref dict: Felt252Dict, key: felt252, value: T) nopanic; @@ -19,9 +21,9 @@ trait Felt252DictTrait { fn new() -> Felt252Dict; fn insert(ref self: Felt252Dict, key: felt252, value: T); fn get(ref self: Felt252Dict, key: felt252) -> T; - fn squash(self: Felt252Dict) -> SquashedFelt252Dict; + fn squash(self: Felt252Dict) -> SquashedFelt252Dict nopanic; } -impl Felt252DictImpl of Felt252DictTrait:: { +impl Felt252DictImpl> of Felt252DictTrait { fn new() -> Felt252Dict { felt252_dict_new() } @@ -32,7 +34,24 @@ impl Felt252DictImpl of Felt252DictTrait:: { felt252_dict_read(ref self, key) } #[inline(never)] - fn squash(self: Felt252Dict) -> SquashedFelt252Dict { + fn squash(self: Felt252Dict) -> SquashedFelt252Dict nopanic { felt252_dict_squash(self) } } + +impl Felt252DictDestruct, +impl TDefault: Felt252DictValue> of Destruct> { + #[inline(always)] + fn destruct(self: Felt252Dict) nopanic { + self.squash(); + } +} + +impl Felt252DictIndex of Index, felt252, T> { + #[inline(always)] + fn index(ref self: Felt252Dict, index: felt252) -> T { + felt252_dict_read(ref self, index) + } +} + diff --git a/corelib/src/ec.cairo b/corelib/src/ec.cairo index 6b00f2ea3..5058361bf 100644 --- a/corelib/src/ec.cairo +++ b/corelib/src/ec.cairo @@ -1,4 +1,6 @@ use array::ArrayTrait; +use zeroable::IsZeroResult; +use traits::Into; mod StarkCurve { /// The STARK Curve is defined by the equation `y^2 = x^3 + ALPHA*x + BETA`. @@ -30,13 +32,13 @@ extern fn ec_point_try_new_nz(x: felt252, y: felt252) -> Option #[inline(always)] fn ec_point_try_new(x: felt252, y: felt252) -> Option { match ec_point_try_new_nz(:x, :y) { - Option::Some(pt) => Option::Some(unwrap_non_zero(pt)), + Option::Some(pt) => Option::Some(pt.into()), Option::None(()) => Option::None(()), } } fn ec_point_new(x: felt252, y: felt252) -> EcPoint { - unwrap_non_zero(ec_point_new_nz(:x, :y)) + ec_point_new_nz(:x, :y).into() } extern fn ec_point_from_x_nz(x: felt252) -> Option implicits(RangeCheck) nopanic; @@ -44,7 +46,7 @@ extern fn ec_point_from_x_nz(x: felt252) -> Option implicits(Ran #[inline(always)] fn ec_point_from_x(x: felt252) -> Option { match ec_point_from_x_nz(:x) { - Option::Some(pt) => Option::Some(unwrap_non_zero(pt)), + Option::Some(pt) => Option::Some(pt.into()), Option::None(()) => Option::None(()), } } @@ -58,11 +60,7 @@ extern fn ec_point_is_zero(p: EcPoint) -> IsZeroResult nopanic; /// Converts `p` to `NonZeroEcPoint`. Panics if `p` is the zero point. fn ec_point_non_zero(p: EcPoint) -> NonZeroEcPoint { match ec_point_is_zero(p) { - IsZeroResult::Zero(()) => { - let mut data = ArrayTrait::new(); - data.append('Zero point'); - panic(data) - }, + IsZeroResult::Zero(()) => panic_with_felt252('Zero point'), IsZeroResult::NonZero(p_nz) => p_nz, } } @@ -85,9 +83,9 @@ extern fn ec_state_add_mul(ref s: EcState, m: felt252, p: NonZeroEcPoint) implic /// Finalizes the EC computation and returns the result. #[inline(always)] -fn ec_state_finalize(s: EcState) -> EcPoint nopanic { +fn ec_state_finalize(s: EcState) -> EcPoint { match ec_state_try_finalize_nz(s) { - Option::Some(pt) => unwrap_non_zero(pt), + Option::Some(pt) => pt.into(), Option::None(()) => ec_point_zero(), } } @@ -104,52 +102,52 @@ fn ec_mul(p: EcPoint, m: felt252) -> EcPoint { } } -impl EcPointAdd of Add:: { +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(p: EcPoint, q: EcPoint) -> EcPoint { - let p_nz = match ec_point_is_zero(p) { + fn add(lhs: EcPoint, rhs: EcPoint) -> EcPoint { + let lhs_nz = match ec_point_is_zero(lhs) { IsZeroResult::Zero(()) => { - return q; + return rhs; }, IsZeroResult::NonZero(pt) => pt, }; - let q_nz = match ec_point_is_zero(q) { + let rhs_nz = match ec_point_is_zero(rhs) { IsZeroResult::Zero(()) => { - return p; + return lhs; }, IsZeroResult::NonZero(pt) => pt, }; let mut state = ec_state_init(); - ec_state_add(ref state, p_nz); - ec_state_add(ref state, q_nz); + ec_state_add(ref state, lhs_nz); + ec_state_add(ref state, rhs_nz); ec_state_finalize(state) } } -impl EcPointAddEq of AddEq:: { +impl EcPointAddEq of AddEq { #[inline(always)] fn add_eq(ref self: EcPoint, other: EcPoint) { self = Add::add(self, other); } } -impl EcPointSub of Sub:: { +impl EcPointSub of Sub { /// Computes the difference between two points on the curve. - fn sub(p: EcPoint, q: EcPoint) -> EcPoint { - match ec_point_is_zero(q) { + fn sub(lhs: EcPoint, rhs: EcPoint) -> EcPoint { + match ec_point_is_zero(rhs) { IsZeroResult::Zero(()) => { - // p - 0 = p. - return p; + // lhs - 0 = lhs. + return lhs; }, IsZeroResult::NonZero(_) => {}, }; - // p - q = p + (-q). - p + ec_neg(q) + // lhs - rhs = lhs + (-rhs). + lhs + ec_neg(rhs) } } -impl EcPointSubEq of SubEq:: { +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 index 869af8e3f..f986f1c4f 100644 --- a/corelib/src/ecdsa.cairo +++ b/corelib/src/ecdsa.cairo @@ -1,3 +1,22 @@ +use zeroable::IsZeroResult; +use ec::ec_mul; +use ec::ec_neg; +use ec::ec_point_from_x; +use ec::ec_point_from_x_nz; +use ec::ec_point_is_zero; +use ec::ec_point_new; +use ec::ec_point_new_nz; +use ec::ec_point_non_zero; +use ec::ec_point_try_new; +use ec::ec_point_try_new_nz; +use ec::ec_point_unwrap; +use ec::ec_point_zero; +use ec::ec_state_add_mul; +use ec::ec_state_add; +use ec::ec_state_finalize; +use ec::ec_state_init; +use ec::ec_state_try_finalize_nz; + // Checks if (`signature_r`, `signature_s`) is a valid ECDSA signature for the given `public_key` // on the given `message`. // diff --git a/corelib/src/hash.cairo b/corelib/src/hash.cairo index f438b00c7..c13bd82c1 100644 --- a/corelib/src/hash.cairo +++ b/corelib/src/hash.cairo @@ -1,5 +1,4 @@ use traits::Into; -use starknet::ContractAddressIntoFelt252; use starknet::ContractAddress; extern type Pedersen; @@ -10,13 +9,13 @@ trait LegacyHash { fn hash(state: felt252, value: T) -> felt252; } -impl LegacyHashFelt252 of LegacyHash:: { +impl LegacyHashFelt252 of LegacyHash { fn hash(state: felt252, value: felt252) -> felt252 { pedersen(state, value) } } -impl LegacyHashBool of LegacyHash:: { +impl LegacyHashBool of LegacyHash { fn hash(state: felt252, value: bool) -> felt252 { LegacyHash::::hash(state, if value { 1 @@ -26,56 +25,56 @@ impl LegacyHashBool of LegacyHash:: { } } -impl LegacyHashU8 of LegacyHash:: { +impl LegacyHashU8 of LegacyHash { fn hash(state: felt252, value: u8) -> felt252 { LegacyHash::::hash(state, value.into()) } } -impl LegacyHashU16 of LegacyHash:: { +impl LegacyHashU16 of LegacyHash { fn hash(state: felt252, value: u16) -> felt252 { LegacyHash::::hash(state, value.into()) } } -impl LegacyHashU32 of LegacyHash:: { +impl LegacyHashU32 of LegacyHash { fn hash(state: felt252, value: u32) -> felt252 { LegacyHash::::hash(state, value.into()) } } -impl LegacyHashU64 of LegacyHash:: { +impl LegacyHashU64 of LegacyHash { fn hash(state: felt252, value: u64) -> felt252 { LegacyHash::::hash(state, value.into()) } } -impl LegacyHashU128 of LegacyHash:: { +impl LegacyHashU128 of LegacyHash { fn hash(state: felt252, value: u128) -> felt252 { LegacyHash::::hash(state, value.into()) } } -impl LegacyHashU256 of LegacyHash:: { +impl LegacyHashU256 of LegacyHash { fn hash(state: felt252, value: u256) -> felt252 { let state = LegacyHash::::hash(state, value.low); LegacyHash::::hash(state, value.high) } } -impl LegacyHashContractAddress of LegacyHash:: { +impl LegacyHashContractAddress of LegacyHash { fn hash(state: felt252, value: starknet::ContractAddress) -> felt252 { LegacyHash::::hash(state, value.into()) } } -impl TupleSize0LegacyHash of LegacyHash::<()> { +impl TupleSize0LegacyHash of LegacyHash<()> { fn hash(state: felt252, value: ()) -> felt252 { state } } -impl TupleSize1LegacyHash> of LegacyHash::<(E0, )> { +impl TupleSize1LegacyHash> of LegacyHash<(E0, )> { fn hash(state: felt252, value: (E0, )) -> felt252 { let (e0, ) = value; E0LegacyHash::hash(state, e0) @@ -84,8 +83,10 @@ impl TupleSize1LegacyHash> of LegacyHash impl TupleSize2LegacyHash, -impl E1LegacyHash: LegacyHash::> of LegacyHash::<(E0, E1)> { +impl E0LegacyHash: LegacyHash, +impl E1LegacyHash: LegacyHash, +impl E0Drop: Drop, +impl E1Drop: Drop> of LegacyHash<(E0, E1)> { fn hash(state: felt252, value: (E0, E1, )) -> felt252 { let (e0, e1) = value; let state = E0LegacyHash::hash(state, e0); @@ -96,9 +97,13 @@ impl E1LegacyHash: LegacyHash::> of LegacyHash::<(E0, E1)> { impl TupleSize3LegacyHash, -impl E1LegacyHash: LegacyHash::, -impl E2LegacyHash: LegacyHash::> of LegacyHash::<(E0, E1, E2)> { +impl E0LegacyHash: LegacyHash, +impl E1LegacyHash: LegacyHash, +impl E2LegacyHash: LegacyHash, +impl E0Drop: Drop, +impl E1Drop: Drop, +impl E2Drop: Drop, +> of LegacyHash<(E0, E1, E2)> { fn hash(state: felt252, value: (E0, E1, E2)) -> felt252 { let (e0, e1, e2) = value; let state = E0LegacyHash::hash(state, e0); @@ -111,10 +116,15 @@ impl TupleSize4LegacyHash, -impl E1LegacyHash: LegacyHash::, -impl E2LegacyHash: LegacyHash::, -impl E3LegacyHash: LegacyHash::> of LegacyHash::<(E0, E1, E2, E3)> { +impl E0LegacyHash: LegacyHash, +impl E1LegacyHash: LegacyHash, +impl E2LegacyHash: LegacyHash, +impl E3LegacyHash: LegacyHash, +impl E0Drop: Drop, +impl E1Drop: Drop, +impl E2Drop: Drop, +impl E3Drop: Drop, +> of LegacyHash<(E0, E1, E2, E3)> { fn hash(state: felt252, value: (E0, E1, E2, E3)) -> felt252 { let (e0, e1, e2, e3) = value; let state = E0LegacyHash::hash(state, e0); diff --git a/corelib/src/integer.cairo b/corelib/src/integer.cairo index d51ef139d..e35d21de6 100644 --- a/corelib/src/integer.cairo +++ b/corelib/src/integer.cairo @@ -1,12 +1,18 @@ -use result::ResultTrait; -use result::ResultTraitImpl; +use zeroable::IsZeroResult; use option::OptionTrait; -use option::OptionTraitImpl; +use result::ResultTrait; use traits::Into; use traits::TryInto; +use traits::Default; +use traits::Felt252DictValue; + +// TODO(spapini): Add method for const creation from Integer. +trait NumericLiteral; +impl NumericLiteralfelt252 of NumericLiteral; #[derive(Copy, Drop)] extern type u128; +impl NumericLiteralu128 of NumericLiteral; extern fn u128_const() -> u128 nopanic; enum U128sFromFelt252Result { @@ -15,7 +21,7 @@ enum U128sFromFelt252Result { } extern fn u128s_from_felt252(a: felt252) -> U128sFromFelt252Result implicits(RangeCheck) nopanic; -#[panic_with('u128_from OF', u128_from_felt252)] +#[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), @@ -26,24 +32,24 @@ fn u128_try_from_felt252(a: felt252) -> Option implicits(RangeCheck) nopan extern fn u128_to_felt252(a: u128) -> felt252 nopanic; extern fn u128_overflowing_add( - a: u128, b: u128 + lhs: u128, rhs: u128 ) -> Result implicits(RangeCheck) nopanic; extern fn u128_overflowing_sub( - a: u128, b: u128 + lhs: u128, rhs: u128 ) -> Result implicits(RangeCheck) nopanic; -fn u128_wrapping_add(a: u128, b: u128) -> u128 implicits(RangeCheck) nopanic { - match u128_overflowing_add(a, b) { +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, } } -extern fn u128_wide_mul(a: u128, b: u128) -> (u128, u128) implicits(RangeCheck) nopanic; +extern fn u128_wide_mul(lhs: u128, rhs: u128) -> (u128, u128) implicits(RangeCheck) nopanic; extern fn u128_sqrt(value: u128) -> u128 implicits(RangeCheck) nopanic; -fn u128_overflowing_mul(a: u128, b: u128) -> (u128, bool) implicits(RangeCheck) nopanic { - let (top_word, bottom_word) = u128_wide_mul(a, b); +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), @@ -51,59 +57,59 @@ fn u128_overflowing_mul(a: u128, b: u128) -> (u128, bool) implicits(RangeCheck) } -fn u128_checked_add(a: u128, b: u128) -> Option implicits(RangeCheck) nopanic { - match u128_overflowing_add(a, b) { +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(a: u128, b: u128) -> u128 { - u128_overflowing_add(a, b).expect('u128_add Overflow') +impl U128Add of Add { + fn add(lhs: u128, rhs: u128) -> u128 { + u128_overflowing_add(lhs, rhs).expect('u128_add Overflow') } } -impl U128AddEq of AddEq:: { +impl U128AddEq of AddEq { #[inline(always)] fn add_eq(ref self: u128, other: u128) { self = Add::add(self, other); } } -#[panic_with('u128_sub OF', u128_sub)] -fn u128_checked_sub(a: u128, b: u128) -> Option implicits(RangeCheck) nopanic { - match u128_overflowing_sub(a, b) { +#[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(a: u128, b: u128) -> u128 { - u128_overflowing_sub(a, b).expect('u128_sub Overflow') +impl U128Sub of Sub { + fn sub(lhs: u128, rhs: u128) -> u128 { + u128_overflowing_sub(lhs, rhs).expect('u128_sub Overflow') } } -impl U128SubEq of SubEq:: { +impl U128SubEq of SubEq { #[inline(always)] fn sub_eq(ref self: u128, other: u128) { self = Sub::sub(self, other); } } -fn u128_checked_mul(a: u128, b: u128) -> Option implicits(RangeCheck) nopanic { - let (top_word, bottom_word) = u128_wide_mul(a, b); +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(a: u128, b: u128) -> u128 { - u128_checked_mul(a, b).expect('u128_mul Overflow') +impl U128Mul of Mul { + fn mul(lhs: u128, rhs: u128) -> u128 { + u128_checked_mul(lhs, rhs).expect('u128_mul Overflow') } } -impl U128MulEq of MulEq:: { +impl U128MulEq of MulEq { #[inline(always)] fn mul_eq(ref self: u128, other: u128) { self = Mul::mul(self, other); @@ -118,88 +124,90 @@ fn u128_try_as_non_zero(a: u128) -> Option> implicits() nopanic { } } -impl U128Div of Div:: { - fn div(a: u128, b: u128) -> u128 { - let (q, r) = u128_safe_divmod(a, u128_as_non_zero(b)); +impl U128Div of Div { + fn div(lhs: u128, rhs: u128) -> u128 { + let (q, r) = u128_safe_divmod(lhs, u128_as_non_zero(rhs)); q } } -impl U128DivEq of DivEq:: { +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(a: u128, b: u128) -> u128 { - let (q, r) = u128_safe_divmod(a, u128_as_non_zero(b)); +impl U128Rem of Rem { + fn rem(lhs: u128, rhs: u128) -> u128 { + let (q, r) = u128_safe_divmod(lhs, u128_as_non_zero(rhs)); r } } -impl U128RemEq of RemEq:: { +impl U128RemEq of RemEq { #[inline(always)] fn rem_eq(ref self: u128, other: u128) { self = Rem::rem(self, other); } } -extern fn u128_safe_divmod(a: u128, b: NonZero) -> (u128, u128) implicits(RangeCheck) nopanic; +extern fn u128_safe_divmod( + lhs: u128, rhs: NonZero +) -> (u128, u128) implicits(RangeCheck) nopanic; -extern fn u128_lt(a: u128, b: u128) -> bool implicits(RangeCheck) nopanic; -extern fn u128_eq(a: u128, b: u128) -> bool implicits() nopanic; -extern fn u128_le(a: u128, b: u128) -> bool implicits(RangeCheck) nopanic; +extern fn u128_lt(lhs: u128, rhs: u128) -> bool implicits(RangeCheck) nopanic; +extern fn u128_eq(lhs: u128, rhs: u128) -> bool implicits() nopanic; +extern fn u128_le(lhs: u128, rhs: u128) -> bool implicits(RangeCheck) nopanic; -impl U128PartialEq of PartialEq:: { +impl U128PartialEq of PartialEq { #[inline(always)] - fn eq(a: u128, b: u128) -> bool { - u128_eq(a, b) + fn eq(lhs: u128, rhs: u128) -> bool { + u128_eq(lhs, rhs) } #[inline(always)] - fn ne(a: u128, b: u128) -> bool { - !(a == b) + fn ne(lhs: u128, rhs: u128) -> bool { + !(lhs == rhs) } } -impl U128PartialOrd of PartialOrd:: { +impl U128PartialOrd of PartialOrd { #[inline(always)] - fn le(a: u128, b: u128) -> bool { - u128_le(a, b) + fn le(lhs: u128, rhs: u128) -> bool { + u128_le(lhs, rhs) } #[inline(always)] - fn ge(a: u128, b: u128) -> bool { - u128_le(b, a) + fn ge(lhs: u128, rhs: u128) -> bool { + u128_le(rhs, lhs) } #[inline(always)] - fn lt(a: u128, b: u128) -> bool { - u128_lt(a, b) + fn lt(lhs: u128, rhs: u128) -> bool { + u128_lt(lhs, rhs) } #[inline(always)] - fn gt(a: u128, b: u128) -> bool { - u128_lt(b, a) + fn gt(lhs: u128, rhs: u128) -> bool { + u128_lt(rhs, lhs) } } extern type Bitwise; -extern fn bitwise(a: u128, b: u128) -> (u128, u128, u128) implicits(Bitwise) nopanic; -impl U128BitAnd of BitAnd:: { +extern fn bitwise(lhs: u128, rhs: u128) -> (u128, u128, u128) implicits(Bitwise) nopanic; +impl U128BitAnd of BitAnd { #[inline(always)] - fn bitand(a: u128, b: u128) -> u128 { - let (v, _, _) = bitwise(a, b); + fn bitand(lhs: u128, rhs: u128) -> u128 { + let (v, _, _) = bitwise(lhs, rhs); v } } -impl U128BitXor of BitXor:: { +impl U128BitXor of BitXor { #[inline(always)] - fn bitxor(a: u128, b: u128) -> u128 { - let (_, v, _) = bitwise(a, b); + fn bitxor(lhs: u128, rhs: u128) -> u128 { + let (_, v, _) = bitwise(lhs, rhs); v } } -impl U128BitOr of BitOr:: { +impl U128BitOr of BitOr { #[inline(always)] - fn bitor(a: u128, b: u128) -> u128 { - let (_, _, v) = bitwise(a, b); + fn bitor(lhs: u128, rhs: u128) -> u128 { + let (_, _, v) = bitwise(lhs, rhs); v } } @@ -208,108 +216,109 @@ extern fn u128_is_zero(a: u128) -> IsZeroResult implicits() nopanic; #[derive(Copy, Drop)] extern type u8; +impl NumericLiteralu8 of NumericLiteral; extern fn u8_const() -> u8 nopanic; extern fn u8_to_felt252(a: u8) -> felt252 nopanic; -#[panic_with('u8_from OF', u8_from_felt252)] +#[panic_with('u8_from Overflow', u8_from_felt252)] extern fn u8_try_from_felt252(a: felt252) -> Option implicits(RangeCheck) nopanic; -extern fn u8_lt(a: u8, b: u8) -> bool implicits(RangeCheck) nopanic; -extern fn u8_eq(a: u8, b: u8) -> bool implicits() nopanic; -extern fn u8_le(a: u8, b: u8) -> bool implicits(RangeCheck) nopanic; +extern fn u8_lt(lhs: u8, rhs: u8) -> bool implicits(RangeCheck) nopanic; +extern fn u8_eq(lhs: u8, rhs: u8) -> bool implicits() nopanic; +extern fn u8_le(lhs: u8, rhs: u8) -> bool implicits(RangeCheck) nopanic; -impl U8PartialEq of PartialEq:: { +impl U8PartialEq of PartialEq { #[inline(always)] - fn eq(a: u8, b: u8) -> bool { - u8_eq(a, b) + fn eq(lhs: u8, rhs: u8) -> bool { + u8_eq(lhs, rhs) } #[inline(always)] - fn ne(a: u8, b: u8) -> bool { - !(a == b) + fn ne(lhs: u8, rhs: u8) -> bool { + !(lhs == rhs) } } -impl U8PartialOrd of PartialOrd:: { +impl U8PartialOrd of PartialOrd { #[inline(always)] - fn le(a: u8, b: u8) -> bool { - u8_le(a, b) + fn le(lhs: u8, rhs: u8) -> bool { + u8_le(lhs, rhs) } #[inline(always)] - fn ge(a: u8, b: u8) -> bool { - u8_le(b, a) + fn ge(lhs: u8, rhs: u8) -> bool { + u8_le(rhs, lhs) } #[inline(always)] - fn lt(a: u8, b: u8) -> bool { - u8_lt(a, b) + fn lt(lhs: u8, rhs: u8) -> bool { + u8_lt(lhs, rhs) } #[inline(always)] - fn gt(a: u8, b: u8) -> bool { - u8_lt(b, a) + fn gt(lhs: u8, rhs: u8) -> bool { + u8_lt(rhs, lhs) } } -extern fn u8_overflowing_add(a: u8, b: u8) -> Result implicits(RangeCheck) nopanic; -extern fn u8_overflowing_sub(a: u8, b: u8) -> Result implicits(RangeCheck) nopanic; +extern fn u8_overflowing_add(lhs: u8, rhs: u8) -> Result implicits(RangeCheck) nopanic; +extern fn u8_overflowing_sub(lhs: u8, rhs: u8) -> Result implicits(RangeCheck) nopanic; -fn u8_wrapping_add(a: u8, b: u8) -> u8 implicits(RangeCheck) nopanic { - match u8_overflowing_add(a, b) { +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, } } -fn u8_wrapping_sub(a: u8, b: u8) -> u8 implicits(RangeCheck) nopanic { - match u8_overflowing_sub(a, b) { +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(a: u8, b: u8) -> Option implicits(RangeCheck) nopanic { - match u8_overflowing_add(a, b) { +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(a: u8, b: u8) -> u8 { - u8_overflowing_add(a, b).expect('u8_add Overflow') +impl U8Add of Add { + fn add(lhs: u8, rhs: u8) -> u8 { + u8_overflowing_add(lhs, rhs).expect('u8_add Overflow') } } -impl U8AddEq of AddEq:: { +impl U8AddEq of AddEq { #[inline(always)] fn add_eq(ref self: u8, other: u8) { self = Add::add(self, other); } } -fn u8_checked_sub(a: u8, b: u8) -> Option implicits(RangeCheck) nopanic { - match u8_overflowing_sub(a, b) { +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(a: u8, b: u8) -> u8 { - u8_overflowing_sub(a, b).expect('u8_sub Overflow') +impl U8Sub of Sub { + fn sub(lhs: u8, rhs: u8) -> u8 { + u8_overflowing_sub(lhs, rhs).expect('u8_sub Overflow') } } -impl U8SubEq of SubEq:: { +impl U8SubEq of SubEq { #[inline(always)] fn sub_eq(ref self: u8, other: u8) { self = Sub::sub(self, other); } } -extern fn u8_wide_mul(a: u8, b: u8) -> u16 implicits() nopanic; -impl U8Mul of Mul:: { - fn mul(a: u8, b: u8) -> u8 { - u8_try_from_felt252(u16_to_felt252(u8_wide_mul(a, b))).expect('u8_mul Overflow') +extern fn u8_wide_mul(lhs: u8, rhs: u8) -> u16 implicits() nopanic; +impl U8Mul of Mul { + fn mul(lhs: u8, rhs: u8) -> u8 { + u8_try_from_felt252(u16_to_felt252(u8_wide_mul(lhs, rhs))).expect('u8_mul Overflow') } } -impl U8MulEq of MulEq:: { +impl U8MulEq of MulEq { #[inline(always)] fn mul_eq(ref self: u8, other: u8) { self = Mul::mul(self, other); @@ -317,7 +326,7 @@ impl U8MulEq of MulEq:: { } extern fn u8_is_zero(a: u8) -> IsZeroResult implicits() nopanic; -extern fn u8_safe_divmod(a: u8, b: NonZero) -> (u8, u8) implicits(RangeCheck) nopanic; +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> implicits() nopanic { @@ -327,26 +336,26 @@ fn u8_try_as_non_zero(a: u8) -> Option> implicits() nopanic { } } -impl U8Div of Div:: { - fn div(a: u8, b: u8) -> u8 { - let (q, r) = u8_safe_divmod(a, u8_as_non_zero(b)); +impl U8Div of Div { + fn div(lhs: u8, rhs: u8) -> u8 { + let (q, r) = u8_safe_divmod(lhs, u8_as_non_zero(rhs)); q } } -impl U8DivEq of DivEq:: { +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(a: u8, b: u8) -> u8 { - let (q, r) = u8_safe_divmod(a, u8_as_non_zero(b)); +impl U8Rem of Rem { + fn rem(lhs: u8, rhs: u8) -> u8 { + let (q, r) = u8_safe_divmod(lhs, u8_as_non_zero(rhs)); r } } -impl U8RemEq of RemEq:: { +impl U8RemEq of RemEq { #[inline(always)] fn rem_eq(ref self: u8, other: u8) { self = Rem::rem(self, other); @@ -355,109 +364,110 @@ impl U8RemEq of RemEq:: { #[derive(Copy, Drop)] extern type u16; +impl NumericLiteralu16 of NumericLiteral; extern fn u16_const() -> u16 nopanic; extern fn u16_to_felt252(a: u16) -> felt252 nopanic; -#[panic_with('u16_from OF', u16_from_felt252)] +#[panic_with('u16_from Overflow', u16_from_felt252)] extern fn u16_try_from_felt252(a: felt252) -> Option implicits(RangeCheck) nopanic; -extern fn u16_lt(a: u16, b: u16) -> bool implicits(RangeCheck) nopanic; -extern fn u16_eq(a: u16, b: u16) -> bool implicits() nopanic; -extern fn u16_le(a: u16, b: u16) -> bool implicits(RangeCheck) nopanic; +extern fn u16_lt(lhs: u16, rhs: u16) -> bool implicits(RangeCheck) nopanic; +extern fn u16_eq(lhs: u16, rhs: u16) -> bool implicits() nopanic; +extern fn u16_le(lhs: u16, rhs: u16) -> bool implicits(RangeCheck) nopanic; -impl U16PartialEq of PartialEq:: { +impl U16PartialEq of PartialEq { #[inline(always)] - fn eq(a: u16, b: u16) -> bool { - u16_eq(a, b) + fn eq(lhs: u16, rhs: u16) -> bool { + u16_eq(lhs, rhs) } #[inline(always)] - fn ne(a: u16, b: u16) -> bool { - !(a == b) + fn ne(lhs: u16, rhs: u16) -> bool { + !(lhs == rhs) } } -impl U16PartialOrd of PartialOrd:: { +impl U16PartialOrd of PartialOrd { #[inline(always)] - fn le(a: u16, b: u16) -> bool { - u16_le(a, b) + fn le(lhs: u16, rhs: u16) -> bool { + u16_le(lhs, rhs) } #[inline(always)] - fn ge(a: u16, b: u16) -> bool { - u16_le(b, a) + fn ge(lhs: u16, rhs: u16) -> bool { + u16_le(rhs, lhs) } #[inline(always)] - fn lt(a: u16, b: u16) -> bool { - u16_lt(a, b) + fn lt(lhs: u16, rhs: u16) -> bool { + u16_lt(lhs, rhs) } #[inline(always)] - fn gt(a: u16, b: u16) -> bool { - u16_lt(b, a) + fn gt(lhs: u16, rhs: u16) -> bool { + u16_lt(rhs, lhs) } } -extern fn u16_overflowing_add(a: u16, b: u16) -> Result implicits(RangeCheck) nopanic; -extern fn u16_overflowing_sub(a: u16, b: u16) -> Result implicits(RangeCheck) nopanic; +extern fn u16_overflowing_add(lhs: u16, rhs: u16) -> Result implicits(RangeCheck) nopanic; +extern fn u16_overflowing_sub(lhs: u16, rhs: u16) -> Result implicits(RangeCheck) nopanic; -fn u16_wrapping_add(a: u16, b: u16) -> u16 implicits(RangeCheck) nopanic { - match u16_overflowing_add(a, b) { +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, } } -fn u16_wrapping_sub(a: u16, b: u16) -> u16 implicits(RangeCheck) nopanic { - match u16_overflowing_sub(a, b) { +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(a: u16, b: u16) -> Option implicits(RangeCheck) nopanic { - match u16_overflowing_add(a, b) { +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(a: u16, b: u16) -> u16 { - u16_overflowing_add(a, b).expect('u16_add Overflow') +impl U16Add of Add { + fn add(lhs: u16, rhs: u16) -> u16 { + u16_overflowing_add(lhs, rhs).expect('u16_add Overflow') } } -impl U16AddEq of AddEq:: { +impl U16AddEq of AddEq { #[inline(always)] fn add_eq(ref self: u16, other: u16) { self = Add::add(self, other); } } -fn u16_checked_sub(a: u16, b: u16) -> Option implicits(RangeCheck) nopanic { - match u16_overflowing_sub(a, b) { +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(a: u16, b: u16) -> u16 { - u16_overflowing_sub(a, b).expect('u16_sub Overflow') +impl U16Sub of Sub { + fn sub(lhs: u16, rhs: u16) -> u16 { + u16_overflowing_sub(lhs, rhs).expect('u16_sub Overflow') } } -impl U16SubEq of SubEq:: { +impl U16SubEq of SubEq { #[inline(always)] fn sub_eq(ref self: u16, other: u16) { self = Sub::sub(self, other); } } -extern fn u16_wide_mul(a: u16, b: u16) -> u32 implicits() nopanic; -impl U16Mul of Mul:: { - fn mul(a: u16, b: u16) -> u16 { +extern fn u16_wide_mul(lhs: u16, rhs: u16) -> u32 implicits() nopanic; +impl U16Mul of Mul { + fn mul(lhs: u16, rhs: u16) -> u16 { // TODO(orizi): Use direct conversion, instead of going through felt252. - u16_try_from_felt252(u32_to_felt252(u16_wide_mul(a, b))).expect('u16_mul Overflow') + u16_try_from_felt252(u32_to_felt252(u16_wide_mul(lhs, rhs))).expect('u16_mul Overflow') } } -impl U16MulEq of MulEq:: { +impl U16MulEq of MulEq { #[inline(always)] fn mul_eq(ref self: u16, other: u16) { self = Mul::mul(self, other); @@ -465,7 +475,7 @@ impl U16MulEq of MulEq:: { } extern fn u16_is_zero(a: u16) -> IsZeroResult implicits() nopanic; -extern fn u16_safe_divmod(a: u16, b: NonZero) -> (u16, u16) implicits(RangeCheck) nopanic; +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> implicits() nopanic { @@ -475,26 +485,26 @@ fn u16_try_as_non_zero(a: u16) -> Option> implicits() nopanic { } } -impl U16Div of Div:: { - fn div(a: u16, b: u16) -> u16 { - let (q, r) = u16_safe_divmod(a, u16_as_non_zero(b)); +impl U16Div of Div { + fn div(lhs: u16, rhs: u16) -> u16 { + let (q, r) = u16_safe_divmod(lhs, u16_as_non_zero(rhs)); q } } -impl U16DivEq of DivEq:: { +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(a: u16, b: u16) -> u16 { - let (q, r) = u16_safe_divmod(a, u16_as_non_zero(b)); +impl U16Rem of Rem { + fn rem(lhs: u16, rhs: u16) -> u16 { + let (q, r) = u16_safe_divmod(lhs, u16_as_non_zero(rhs)); r } } -impl U16RemEq of RemEq:: { +impl U16RemEq of RemEq { #[inline(always)] fn rem_eq(ref self: u16, other: u16) { self = Rem::rem(self, other); @@ -503,109 +513,110 @@ impl U16RemEq of RemEq:: { #[derive(Copy, Drop)] extern type u32; +impl NumericLiteralu32 of NumericLiteral; extern fn u32_const() -> u32 nopanic; extern fn u32_to_felt252(a: u32) -> felt252 nopanic; -#[panic_with('u32_from OF', u32_from_felt252)] +#[panic_with('u32_from Overflow', u32_from_felt252)] extern fn u32_try_from_felt252(a: felt252) -> Option implicits(RangeCheck) nopanic; -extern fn u32_lt(a: u32, b: u32) -> bool implicits(RangeCheck) nopanic; -extern fn u32_eq(a: u32, b: u32) -> bool implicits() nopanic; -extern fn u32_le(a: u32, b: u32) -> bool implicits(RangeCheck) nopanic; +extern fn u32_lt(lhs: u32, rhs: u32) -> bool implicits(RangeCheck) nopanic; +extern fn u32_eq(lhs: u32, rhs: u32) -> bool implicits() nopanic; +extern fn u32_le(lhs: u32, rhs: u32) -> bool implicits(RangeCheck) nopanic; -impl U32PartialEq of PartialEq:: { +impl U32PartialEq of PartialEq { #[inline(always)] - fn eq(a: u32, b: u32) -> bool { - u32_eq(a, b) + fn eq(lhs: u32, rhs: u32) -> bool { + u32_eq(lhs, rhs) } #[inline(always)] - fn ne(a: u32, b: u32) -> bool { - !(a == b) + fn ne(lhs: u32, rhs: u32) -> bool { + !(lhs == rhs) } } -impl U32PartialOrd of PartialOrd:: { +impl U32PartialOrd of PartialOrd { #[inline(always)] - fn le(a: u32, b: u32) -> bool { - u32_le(a, b) + fn le(lhs: u32, rhs: u32) -> bool { + u32_le(lhs, rhs) } #[inline(always)] - fn ge(a: u32, b: u32) -> bool { - u32_le(b, a) + fn ge(lhs: u32, rhs: u32) -> bool { + u32_le(rhs, lhs) } #[inline(always)] - fn lt(a: u32, b: u32) -> bool { - u32_lt(a, b) + fn lt(lhs: u32, rhs: u32) -> bool { + u32_lt(lhs, rhs) } #[inline(always)] - fn gt(a: u32, b: u32) -> bool { - u32_lt(b, a) + fn gt(lhs: u32, rhs: u32) -> bool { + u32_lt(rhs, lhs) } } -extern fn u32_overflowing_add(a: u32, b: u32) -> Result implicits(RangeCheck) nopanic; -extern fn u32_overflowing_sub(a: u32, b: u32) -> Result implicits(RangeCheck) nopanic; +extern fn u32_overflowing_add(lhs: u32, rhs: u32) -> Result implicits(RangeCheck) nopanic; +extern fn u32_overflowing_sub(lhs: u32, rhs: u32) -> Result implicits(RangeCheck) nopanic; -fn u32_wrapping_add(a: u32, b: u32) -> u32 implicits(RangeCheck) nopanic { - match u32_overflowing_add(a, b) { +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, } } -fn u32_wrapping_sub(a: u32, b: u32) -> u32 implicits(RangeCheck) nopanic { - match u32_overflowing_sub(a, b) { +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(a: u32, b: u32) -> Option implicits(RangeCheck) nopanic { - match u32_overflowing_add(a, b) { +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(a: u32, b: u32) -> u32 { - u32_overflowing_add(a, b).expect('u32_add Overflow') +impl U32Add of Add { + fn add(lhs: u32, rhs: u32) -> u32 { + u32_overflowing_add(lhs, rhs).expect('u32_add Overflow') } } -impl U32AddEq of AddEq:: { +impl U32AddEq of AddEq { #[inline(always)] fn add_eq(ref self: u32, other: u32) { self = Add::add(self, other); } } -fn u32_checked_sub(a: u32, b: u32) -> Option implicits(RangeCheck) nopanic { - match u32_overflowing_sub(a, b) { +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(a: u32, b: u32) -> u32 { - u32_overflowing_sub(a, b).expect('u32_sub Overflow') +impl U32Sub of Sub { + fn sub(lhs: u32, rhs: u32) -> u32 { + u32_overflowing_sub(lhs, rhs).expect('u32_sub Overflow') } } -impl U32SubEq of SubEq:: { +impl U32SubEq of SubEq { #[inline(always)] fn sub_eq(ref self: u32, other: u32) { self = Sub::sub(self, other); } } -extern fn u32_wide_mul(a: u32, b: u32) -> u64 implicits() nopanic; -impl U32Mul of Mul:: { - fn mul(a: u32, b: u32) -> u32 { +extern fn u32_wide_mul(lhs: u32, rhs: u32) -> u64 implicits() nopanic; +impl U32Mul of Mul { + fn mul(lhs: u32, rhs: u32) -> u32 { // TODO(orizi): Use direct conversion, instead of going through felt252. - u32_try_from_felt252(u64_to_felt252(u32_wide_mul(a, b))).expect('u32_mul Overflow') + u32_try_from_felt252(u64_to_felt252(u32_wide_mul(lhs, rhs))).expect('u32_mul Overflow') } } -impl U32MulEq of MulEq:: { +impl U32MulEq of MulEq { #[inline(always)] fn mul_eq(ref self: u32, other: u32) { self = Mul::mul(self, other); @@ -613,7 +624,7 @@ impl U32MulEq of MulEq:: { } extern fn u32_is_zero(a: u32) -> IsZeroResult implicits() nopanic; -extern fn u32_safe_divmod(a: u32, b: NonZero) -> (u32, u32) implicits(RangeCheck) nopanic; +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> implicits() nopanic { @@ -623,26 +634,26 @@ fn u32_try_as_non_zero(a: u32) -> Option> implicits() nopanic { } } -impl U32Div of Div:: { - fn div(a: u32, b: u32) -> u32 { - let (q, r) = u32_safe_divmod(a, u32_as_non_zero(b)); +impl U32Div of Div { + fn div(lhs: u32, rhs: u32) -> u32 { + let (q, r) = u32_safe_divmod(lhs, u32_as_non_zero(rhs)); q } } -impl U32DivEq of DivEq:: { +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(a: u32, b: u32) -> u32 { - let (q, r) = u32_safe_divmod(a, u32_as_non_zero(b)); +impl U32Rem of Rem { + fn rem(lhs: u32, rhs: u32) -> u32 { + let (q, r) = u32_safe_divmod(lhs, u32_as_non_zero(rhs)); r } } -impl U32RemEq of RemEq:: { +impl U32RemEq of RemEq { #[inline(always)] fn rem_eq(ref self: u32, other: u32) { self = Rem::rem(self, other); @@ -651,109 +662,110 @@ impl U32RemEq of RemEq:: { #[derive(Copy, Drop)] extern type u64; +impl NumericLiteralu64 of NumericLiteral; extern fn u64_const() -> u64 nopanic; extern fn u64_to_felt252(a: u64) -> felt252 nopanic; -#[panic_with('u64_from OF', u64_from_felt252)] +#[panic_with('u64_from Overflow', u64_from_felt252)] extern fn u64_try_from_felt252(a: felt252) -> Option implicits(RangeCheck) nopanic; -extern fn u64_lt(a: u64, b: u64) -> bool implicits(RangeCheck) nopanic; -extern fn u64_eq(a: u64, b: u64) -> bool implicits() nopanic; -extern fn u64_le(a: u64, b: u64) -> bool implicits(RangeCheck) nopanic; +extern fn u64_lt(lhs: u64, rhs: u64) -> bool implicits(RangeCheck) nopanic; +extern fn u64_eq(lhs: u64, rhs: u64) -> bool implicits() nopanic; +extern fn u64_le(lhs: u64, rhs: u64) -> bool implicits(RangeCheck) nopanic; -impl U64PartialEq of PartialEq:: { +impl U64PartialEq of PartialEq { #[inline(always)] - fn eq(a: u64, b: u64) -> bool { - u64_eq(a, b) + fn eq(lhs: u64, rhs: u64) -> bool { + u64_eq(lhs, rhs) } #[inline(always)] - fn ne(a: u64, b: u64) -> bool { - !(a == b) + fn ne(lhs: u64, rhs: u64) -> bool { + !(lhs == rhs) } } -impl U64PartialOrd of PartialOrd:: { +impl U64PartialOrd of PartialOrd { #[inline(always)] - fn le(a: u64, b: u64) -> bool { - u64_le(a, b) + fn le(lhs: u64, rhs: u64) -> bool { + u64_le(lhs, rhs) } #[inline(always)] - fn ge(a: u64, b: u64) -> bool { - u64_le(b, a) + fn ge(lhs: u64, rhs: u64) -> bool { + u64_le(rhs, lhs) } #[inline(always)] - fn lt(a: u64, b: u64) -> bool { - u64_lt(a, b) + fn lt(lhs: u64, rhs: u64) -> bool { + u64_lt(lhs, rhs) } #[inline(always)] - fn gt(a: u64, b: u64) -> bool { - u64_lt(b, a) + fn gt(lhs: u64, rhs: u64) -> bool { + u64_lt(rhs, lhs) } } -extern fn u64_overflowing_add(a: u64, b: u64) -> Result implicits(RangeCheck) nopanic; -extern fn u64_overflowing_sub(a: u64, b: u64) -> Result implicits(RangeCheck) nopanic; +extern fn u64_overflowing_add(lhs: u64, rhs: u64) -> Result implicits(RangeCheck) nopanic; +extern fn u64_overflowing_sub(lhs: u64, rhs: u64) -> Result implicits(RangeCheck) nopanic; -fn u64_wrapping_add(a: u64, b: u64) -> u64 implicits(RangeCheck) nopanic { - match u64_overflowing_add(a, b) { +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, } } -fn u64_wrapping_sub(a: u64, b: u64) -> u64 implicits(RangeCheck) nopanic { - match u64_overflowing_sub(a, b) { +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(a: u64, b: u64) -> Option implicits(RangeCheck) nopanic { - match u64_overflowing_add(a, b) { +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(a: u64, b: u64) -> u64 { - u64_overflowing_add(a, b).expect('u64_add Overflow') +impl U64Add of Add { + fn add(lhs: u64, rhs: u64) -> u64 { + u64_overflowing_add(lhs, rhs).expect('u64_add Overflow') } } -impl U64AddEq of AddEq:: { +impl U64AddEq of AddEq { #[inline(always)] fn add_eq(ref self: u64, other: u64) { self = Add::add(self, other); } } -fn u64_checked_sub(a: u64, b: u64) -> Option implicits(RangeCheck) nopanic { - match u64_overflowing_sub(a, b) { +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(a: u64, b: u64) -> u64 { - u64_overflowing_sub(a, b).expect('u64_sub Overflow') +impl U64Sub of Sub { + fn sub(lhs: u64, rhs: u64) -> u64 { + u64_overflowing_sub(lhs, rhs).expect('u64_sub Overflow') } } -impl U64SubEq of SubEq:: { +impl U64SubEq of SubEq { #[inline(always)] fn sub_eq(ref self: u64, other: u64) { self = Sub::sub(self, other); } } -extern fn u64_wide_mul(a: u64, b: u64) -> u128 implicits() nopanic; -impl U64Mul of Mul:: { - fn mul(a: u64, b: u64) -> u64 { +extern fn u64_wide_mul(lhs: u64, rhs: u64) -> u128 implicits() nopanic; +impl U64Mul of Mul { + fn mul(lhs: u64, rhs: u64) -> u64 { // TODO(orizi): Use direct conversion, instead of going through felt252. - u64_try_from_felt252(u128_to_felt252(u64_wide_mul(a, b))).expect('u64_mul Overflow') + u64_try_from_felt252(u128_to_felt252(u64_wide_mul(lhs, rhs))).expect('u64_mul Overflow') } } -impl U64MulEq of MulEq:: { +impl U64MulEq of MulEq { #[inline(always)] fn mul_eq(ref self: u64, other: u64) { self = Mul::mul(self, other); @@ -761,7 +773,7 @@ impl U64MulEq of MulEq:: { } extern fn u64_is_zero(a: u64) -> IsZeroResult implicits() nopanic; -extern fn u64_safe_divmod(a: u64, b: NonZero) -> (u64, u64) implicits(RangeCheck) nopanic; +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> implicits() nopanic { @@ -771,44 +783,44 @@ fn u64_try_as_non_zero(a: u64) -> Option> implicits() nopanic { } } -impl U64Div of Div:: { - fn div(a: u64, b: u64) -> u64 { - let (q, r) = u64_safe_divmod(a, u64_as_non_zero(b)); +impl U64Div of Div { + fn div(lhs: u64, rhs: u64) -> u64 { + let (q, r) = u64_safe_divmod(lhs, u64_as_non_zero(rhs)); q } } -impl U64DivEq of DivEq:: { +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(a: u64, b: u64) -> u64 { - let (q, r) = u64_safe_divmod(a, u64_as_non_zero(b)); +impl U64Rem of Rem { + fn rem(lhs: u64, rhs: u64) -> u64 { + let (q, r) = u64_safe_divmod(lhs, u64_as_non_zero(rhs)); r } } -impl U64RemEq of RemEq:: { +impl U64RemEq of RemEq { #[inline(always)] fn rem_eq(ref self: u64, other: u64) { self = Rem::rem(self, other); } } -#[derive(Copy, Drop)] +#[derive(Copy, Drop, PartialEq, Serde)] struct u256 { low: u128, high: u128, } -fn u256_overflowing_add(a: u256, b: u256) -> (u256, bool) implicits(RangeCheck) nopanic { - let (high, overflow) = match u128_overflowing_add(a.high, b.high) { +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(a.low, b.low) { + 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) { @@ -819,12 +831,12 @@ fn u256_overflowing_add(a: u256, b: u256) -> (u256, bool) implicits(RangeCheck) } } -fn u256_overflow_sub(a: u256, b: u256) -> (u256, bool) implicits(RangeCheck) nopanic { - let (high, overflow) = match u128_overflowing_sub(a.high, b.high) { +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(a.low, b.low) { + 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) { @@ -835,14 +847,14 @@ fn u256_overflow_sub(a: u256, b: u256) -> (u256, bool) implicits(RangeCheck) nop } } -fn u256_overflow_mul(a: u256, b: u256) -> (u256, bool) { - let (high1, low) = u128_wide_mul(a.low, b.low); - let (overflow_value1, high2) = u128_wide_mul(a.low, b.high); - let (overflow_value2, high3) = u128_wide_mul(a.high, b.low); +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 | (a.high > 0_u128 & b.high > 0_u128) + overflow_value1 != 0_u128 | overflow_value2 != 0_u128 | (lhs.high > 0_u128 & rhs.high > 0_u128) ), Result::Err(high) => (high, true), }; @@ -853,8 +865,8 @@ fn u256_overflow_mul(a: u256, b: u256) -> (u256, bool) { (u256 { low, high }, overflow) } -fn u256_checked_add(a: u256, b: u256) -> Option implicits(RangeCheck) nopanic { - let (r, overflow) = u256_overflowing_add(a, b); +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 { @@ -862,21 +874,21 @@ fn u256_checked_add(a: u256, b: u256) -> Option implicits(RangeCheck) nopa } } -impl U256Add of Add:: { - fn add(a: u256, b: u256) -> u256 { - u256_checked_add(a, b).expect('u256_add Overflow') +impl U256Add of Add { + fn add(lhs: u256, rhs: u256) -> u256 { + u256_checked_add(lhs, rhs).expect('u256_add Overflow') } } -impl U256AddEq of AddEq:: { +impl U256AddEq of AddEq { #[inline(always)] fn add_eq(ref self: u256, other: u256) { self = Add::add(self, other); } } -#[panic_with('u256_sub OF', u256_sub)] -fn u256_checked_sub(a: u256, b: u256) -> Option implicits(RangeCheck) nopanic { - let (r, overflow) = u256_overflow_sub(a, b); +#[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 { @@ -884,20 +896,20 @@ fn u256_checked_sub(a: u256, b: u256) -> Option implicits(RangeCheck) nopa } } -impl U256Sub of Sub:: { - fn sub(a: u256, b: u256) -> u256 { - u256_checked_sub(a, b).expect('u256_sub Overflow') +impl U256Sub of Sub { + fn sub(lhs: u256, rhs: u256) -> u256 { + u256_checked_sub(lhs, rhs).expect('u256_sub Overflow') } } -impl U256SubEq of SubEq:: { +impl U256SubEq of SubEq { #[inline(always)] fn sub_eq(ref self: u256, other: u256) { self = Sub::sub(self, other); } } -fn u256_checked_mul(a: u256, b: u256) -> Option implicits(RangeCheck) { - let (r, overflow) = u256_overflow_mul(a, b); +fn u256_checked_mul(lhs: u256, rhs: u256) -> Option implicits(RangeCheck) { + let (r, overflow) = u256_overflow_mul(lhs, rhs); if overflow { Option::None(()) } else { @@ -905,157 +917,258 @@ fn u256_checked_mul(a: u256, b: u256) -> Option implicits(RangeCheck) { } } -impl U256Mul of Mul:: { - fn mul(a: u256, b: u256) -> u256 { - u256_checked_mul(a, b).expect('u256_mul Overflow') +impl U256Mul of Mul { + fn mul(lhs: u256, rhs: u256) -> u256 { + u256_checked_mul(lhs, rhs).expect('u256_mul Overflow') } } -impl U256MulEq of MulEq:: { +impl U256MulEq of MulEq { #[inline(always)] fn mul_eq(ref self: u256, other: u256) { self = Mul::mul(self, other); } } -impl U256PartialEq of PartialEq:: { +impl U256PartialOrd of PartialOrd { #[inline(always)] - fn eq(a: u256, b: u256) -> bool { - a.low == b.low & a.high == b.high + fn le(lhs: u256, rhs: u256) -> bool { + !(rhs < lhs) } #[inline(always)] - fn ne(a: u256, b: u256) -> bool { - !(a == b) - } -} - -impl U256PartialOrd of PartialOrd:: { - #[inline(always)] - fn le(a: u256, b: u256) -> bool { - !(b < a) + fn ge(lhs: u256, rhs: u256) -> bool { + !(lhs < rhs) } - #[inline(always)] - fn ge(a: u256, b: u256) -> bool { - !(a < b) - } - fn lt(a: u256, b: u256) -> bool { - if a.high < b.high { + fn lt(lhs: u256, rhs: u256) -> bool { + if lhs.high < rhs.high { true - } else if a.high == b.high { - a.low < b.low + } else if lhs.high == rhs.high { + lhs.low < rhs.low } else { false } } #[inline(always)] - fn gt(a: u256, b: u256) -> bool { - b < a + fn gt(lhs: u256, rhs: u256) -> bool { + rhs < lhs } } -impl U256BitAnd of BitAnd:: { +impl U256BitAnd of BitAnd { #[inline(always)] - fn bitand(a: u256, b: u256) -> u256 { - u256 { low: a.low & b.low, high: a.high & b.high } + fn bitand(lhs: u256, rhs: u256) -> u256 { + u256 { low: lhs.low & rhs.low, high: lhs.high & rhs.high } } } -impl U256BitXor of BitXor:: { +impl U256BitXor of BitXor { #[inline(always)] - fn bitxor(a: u256, b: u256) -> u256 { - u256 { low: a.low ^ b.low, high: a.high ^ b.high } + fn bitxor(lhs: u256, rhs: u256) -> u256 { + u256 { low: lhs.low ^ rhs.low, high: lhs.high ^ rhs.high } } } -impl U256BitOr of BitOr:: { +impl U256BitOr of BitOr { #[inline(always)] - fn bitor(a: u256, b: u256) -> u256 { - u256 { low: a.low | b.low, high: a.high | b.high } + fn bitor(lhs: u256, rhs: u256) -> u256 { + u256 { low: lhs.low | rhs.low, high: lhs.high | rhs.high } } } -fn u256_from_felt252(a: felt252) -> u256 implicits(RangeCheck) nopanic { - match u128s_from_felt252(a) { +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; +extern fn u256_safe_divmod( + lhs: u256, rhs: NonZero +) -> (u256, u256) implicits(RangeCheck) nopanic; + +#[panic_with('u256 is 0', u256_as_non_zero)] +fn u256_try_as_non_zero(a: u256) -> Option> implicits() nopanic { + match u256_is_zero(a) { + IsZeroResult::Zero(()) => Option::None(()), + IsZeroResult::NonZero(x) => Option::Some(x), + } +} + +impl U256Div of Div { + fn div(lhs: u256, rhs: u256) -> u256 { + let (q, r) = u256_safe_divmod(lhs, u256_as_non_zero(rhs)); + 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_divmod(lhs, u256_as_non_zero(rhs)); + r + } +} +impl U256RemEq of RemEq { + #[inline(always)] + fn rem_eq(ref self: u256, other: u256) { + self = Rem::rem(self, other); + } +} + + +/// Bounded +trait BoundedInt { + fn min() -> T nopanic; + 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 { + u256 { low: 0_u128, high: 0_u128 } + } + #[inline(always)] + fn max() -> u256 nopanic { + u256 { low: BoundedInt::max(), high: BoundedInt::max() } + } +} + /// Conversions. -impl Felt252TryIntoU8 of TryInto:: { +impl Felt252TryIntoU8 of TryInto { fn try_into(self: felt252) -> Option { u8_try_from_felt252(self) } } -impl U8IntoFelt252 of Into:: { +impl U8IntoFelt252 of Into { fn into(self: u8) -> felt252 { u8_to_felt252(self) } } -impl Felt252TryIntoU16 of TryInto:: { +impl Felt252TryIntoU16 of TryInto { fn try_into(self: felt252) -> Option { u16_try_from_felt252(self) } } -impl U16IntoFelt252 of Into:: { +impl U16IntoFelt252 of Into { fn into(self: u16) -> felt252 { u16_to_felt252(self) } } -impl Felt252TryIntoU32 of TryInto:: { +impl Felt252TryIntoU32 of TryInto { fn try_into(self: felt252) -> Option { u32_try_from_felt252(self) } } -impl U32IntoFelt252 of Into:: { +impl U32IntoFelt252 of Into { fn into(self: u32) -> felt252 { u32_to_felt252(self) } } -impl Felt252TryIntoU64 of TryInto:: { +impl Felt252TryIntoU64 of TryInto { fn try_into(self: felt252) -> Option { u64_try_from_felt252(self) } } -impl U64IntoFelt252 of Into:: { +impl U64IntoFelt252 of Into { fn into(self: u64) -> felt252 { u64_to_felt252(self) } } -impl Felt252TryIntoU128 of TryInto:: { +impl Felt252TryIntoU128 of TryInto { fn try_into(self: felt252) -> Option { u128_try_from_felt252(self) } } -impl U128IntoFelt252 of Into:: { +impl U128IntoFelt252 of Into { fn into(self: u128) -> felt252 { u128_to_felt252(self) } } -impl Felt252IntoU256 of Into:: { +impl Felt252IntoU256 of Into { fn into(self: felt252) -> u256 { u256_from_felt252(self) } } -impl U16TryIntoU8 of TryInto:: { +impl U16TryIntoU8 of TryInto { fn try_into(self: u16) -> Option { // TODO(orizi): Use direct conversion, instead of going through felt252. let as_felt252: felt252 = self.into(); as_felt252.try_into() } } -impl U32TryIntoU16 of TryInto:: { +impl U32TryIntoU16 of TryInto { fn try_into(self: u32) -> Option { // TODO(orizi): Use direct conversion, instead of going through felt252. let as_felt: felt252 = self.into(); as_felt.try_into() } } -impl U64TryIntoU32 of TryInto:: { +impl U64TryIntoU32 of TryInto { fn try_into(self: u64) -> Option { // TODO(orizi): Use direct conversion, instead of going through felt252. let as_felt: felt252 = self.into(); as_felt.try_into() } } -impl U128TryIntoU64 of TryInto:: { +impl U128TryIntoU64 of TryInto { fn try_into(self: u128) -> Option { // TODO(orizi): Use direct conversion, instead of going through felt252. let as_felt: felt252 = self.into(); @@ -1069,4 +1182,84 @@ 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; +extern fn downcast(x: FromType) -> Option implicits(RangeCheck) nopanic; + +/// 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 { + u256 { low: 0_u128, high: 0_u128 } + } +} + + +/// 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 + } +} diff --git a/corelib/src/lib.cairo b/corelib/src/lib.cairo index c87e8e411..e1c8339ea 100644 --- a/corelib/src/lib.cairo +++ b/corelib/src/lib.cairo @@ -16,10 +16,27 @@ use traits::Rem; use traits::RemEq; use traits::Sub; use traits::SubEq; +use traits::TupleSize0Copy; +use traits::TupleSize0Drop; +use traits::TupleSize0PartialEq; +use traits::TupleSize1Copy; +use traits::TupleSize1Drop; +use traits::TupleSize1PartialEq; +use traits::TupleSize2Copy; +use traits::TupleSize2Drop; +use traits::TupleSize3Copy; +use traits::TupleSize3Drop; +use traits::TupleSize4Copy; +use traits::TupleSize4Drop; use traits::Not; use traits::Neg; use traits::Into; use traits::TryInto; +use traits::Index; +use traits::IndexView; +use traits::Destruct; +use traits::Default; +use traits::Felt252DictValue; #[derive(Copy, Drop)] enum bool { @@ -27,27 +44,27 @@ enum bool { True: (), } -extern fn bool_and_impl(a: bool, b: bool) -> (bool, ) implicits() nopanic; -impl BoolBitAnd of BitAnd:: { +extern fn bool_and_impl(lhs: bool, rhs: bool) -> (bool, ) implicits() nopanic; +impl BoolBitAnd of BitAnd { #[inline(always)] - fn bitand(a: bool, b: bool) -> bool { - let (r, ) = bool_and_impl(a, b); + fn bitand(lhs: bool, rhs: bool) -> bool { + let (r, ) = bool_and_impl(lhs, rhs); r } } -extern fn bool_or_impl(a: bool, b: bool) -> (bool, ) implicits() nopanic; -impl BoolBitOr of BitOr:: { +extern fn bool_or_impl(lhs: bool, rhs: bool) -> (bool, ) implicits() nopanic; +impl BoolBitOr of BitOr { #[inline(always)] - fn bitor(a: bool, b: bool) -> bool { - let (r, ) = bool_or_impl(a, b); + 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:: { +impl BoolNot of Not { #[inline(always)] fn not(a: bool) -> bool implicits() nopanic { let (r, ) = bool_not_impl(a); @@ -55,23 +72,24 @@ impl BoolNot of Not:: { } } -extern fn bool_xor_impl(a: bool, b: bool) -> (bool, ) implicits() nopanic; -impl BoolBitXor of BitXor:: { +extern fn bool_xor_impl(lhs: bool, rhs: bool) -> (bool, ) implicits() nopanic; +impl BoolBitXor of BitXor { #[inline(always)] - fn bitxor(a: bool, b: bool) -> bool { - let (r, ) = bool_xor_impl(a, b); + fn bitxor(lhs: bool, rhs: bool) -> bool { + let (r, ) = bool_xor_impl(lhs, rhs); r } } -impl BoolPartialEq of PartialEq:: { +extern fn bool_eq(lhs: bool, rhs: bool) -> bool implicits() nopanic; +impl BoolPartialEq of PartialEq { #[inline(always)] - fn eq(a: bool, b: bool) -> bool { - bool_to_felt252(a) == bool_to_felt252(b) + fn eq(lhs: bool, rhs: bool) -> bool { + bool_eq(lhs, rhs) } #[inline(always)] - fn ne(a: bool, b: bool) -> bool { - !(a == b) + fn ne(lhs: bool, rhs: bool) -> bool { + !(lhs == rhs) } } @@ -84,94 +102,90 @@ extern type SegmentArena; // felt252. #[derive(Copy, Drop)] extern type felt252; -extern fn felt252_const() -> felt252 nopanic; +extern fn felt252_const() -> felt252 nopanic; -impl Felt252Add of Add:: { +impl Felt252Add of Add { #[inline(always)] - fn add(a: felt252, b: felt252) -> felt252 { - felt252_add(a, b) + fn add(lhs: felt252, rhs: felt252) -> felt252 { + felt252_add(lhs, rhs) } } -impl Felt252AddEq of AddEq:: { +impl Felt252AddEq of AddEq { #[inline(always)] fn add_eq(ref self: felt252, other: felt252) { self = Add::add(self, other); } } -extern fn felt252_add(a: felt252, b: felt252) -> felt252 nopanic; -impl Felt252Sub of Sub:: { +extern fn felt252_add(lhs: felt252, rhs: felt252) -> felt252 nopanic; +impl Felt252Sub of Sub { #[inline(always)] - fn sub(a: felt252, b: felt252) -> felt252 { - felt252_sub(a, b) + fn sub(lhs: felt252, rhs: felt252) -> felt252 { + felt252_sub(lhs, rhs) } } -impl Felt252SubEq of SubEq:: { +impl Felt252SubEq of SubEq { #[inline(always)] fn sub_eq(ref self: felt252, other: felt252) { self = Sub::sub(self, other); } } -extern fn felt252_sub(a: felt252, b: felt252) -> felt252 nopanic; -impl Felt252Mul of Mul:: { +extern fn felt252_sub(lhs: felt252, rhs: felt252) -> felt252 nopanic; +impl Felt252Mul of Mul { #[inline(always)] - fn mul(a: felt252, b: felt252) -> felt252 { - felt252_mul(a, b) + fn mul(lhs: felt252, rhs: felt252) -> felt252 { + felt252_mul(lhs, rhs) } } -impl Felt252MulEq of MulEq:: { +impl Felt252MulEq of MulEq { #[inline(always)] fn mul_eq(ref self: felt252, other: felt252) { self = Mul::mul(self, other); } } -extern fn felt252_mul(a: felt252, b: felt252) -> felt252 nopanic; +extern fn felt252_mul(lhs: felt252, rhs: felt252) -> felt252 nopanic; -impl Felt252Neg of Neg:: { +impl Felt252Neg of Neg { #[inline(always)] fn neg(a: felt252) -> felt252 { a * felt252_const::<-1>() } } -extern type NonZero; -impl NonZeroTCopy> of Copy::>; -impl NonZeroTDrop> of Drop::>; -enum IsZeroResult { - Zero: (), - NonZero: NonZero, -} -extern fn unwrap_non_zero(a: NonZero) -> T nopanic; +extern fn felt252_div(lhs: felt252, rhs: NonZero) -> felt252 nopanic; -impl IsZeroResultIntoBool> of Into::, bool> { - fn into(self: IsZeroResult) -> bool { - match self { - IsZeroResult::Zero(()) => true, - IsZeroResult::NonZero(_) => false, +impl Felt252PartialEq of PartialEq { + #[inline(always)] + fn eq(lhs: felt252, rhs: felt252) -> bool { + match lhs - rhs { + 0 => bool::True(()), + _ => bool::False(()), } } + #[inline(always)] + fn ne(lhs: felt252, rhs: felt252) -> bool { + !(lhs == rhs) + } } -extern fn felt252_div(a: felt252, b: NonZero) -> felt252 nopanic; +extern fn felt252_is_zero(lhs: felt252) -> zeroable::IsZeroResult nopanic; -impl Felt252PartialEq of PartialEq:: { +impl Felt252Default of Default { #[inline(always)] - fn eq(a: felt252, b: felt252) -> bool { - match a - b { - 0 => bool::True(()), - _ => bool::False(()), - } + fn default() -> felt252 nopanic { + 0 } +} + +impl Felt252Felt252DictValue of Felt252DictValue { #[inline(always)] - fn ne(a: felt252, b: felt252) -> bool { - !(a == b) + fn zero_default() -> felt252 nopanic { + 0 } } -extern fn felt252_is_zero(a: felt252) -> IsZeroResult nopanic; - // TODO(spapini): Constraint using Copy and Drop traits. extern fn dup(obj: T) -> (T, T) nopanic; extern fn drop(obj: T) nopanic; @@ -183,7 +197,6 @@ use box::BoxTrait; // Nullable mod nullable; -use nullable::FromNullableResult; use nullable::Nullable; use nullable::match_nullable; use nullable::null; @@ -193,7 +206,6 @@ use nullable::nullable_from_box; mod array; use array::Array; use array::ArrayTrait; -use array::ArrayImpl; type usize = u32; // Span. @@ -209,7 +221,6 @@ use dict::felt252_dict_write; use dict::felt252_dict_read; use dict::felt252_dict_squash; use dict::Felt252DictTrait; -use dict::Felt252DictImpl; // Result. mod result; @@ -218,131 +229,35 @@ use result::Result; // Option. mod option; use option::Option; -use option::OptionCopy; -use option::OptionDrop; // Clone. mod clone; use clone::Clone; -use clone::TCopyClone; // EC. mod ec; use ec::EcOp; use ec::EcPoint; -use ec::EcPointAdd; -use ec::EcPointSub; use ec::EcState; -use ec::NonZeroEcPoint; -use ec::ec_mul; -use ec::ec_neg; -use ec::ec_point_from_x; -use ec::ec_point_from_x_nz; -use ec::ec_point_is_zero; -use ec::ec_point_new; -use ec::ec_point_new_nz; -use ec::ec_point_non_zero; -use ec::ec_point_try_new; -use ec::ec_point_try_new_nz; -use ec::ec_point_unwrap; -use ec::ec_point_zero; -use ec::ec_state_add_mul; -use ec::ec_state_add; -use ec::ec_state_finalize; -use ec::ec_state_init; -use ec::ec_state_try_finalize_nz; mod ecdsa; // Integer. mod integer; +use integer::NumericLiteral; use integer::u128; use integer::u128_const; use integer::u128_sqrt; -use integer::U128Add; -use integer::U128Sub; -use integer::U128Mul; -use integer::U128Div; -use integer::U128Rem; -use integer::U128AddEq; -use integer::U128SubEq; -use integer::U128MulEq; -use integer::U128DivEq; -use integer::U128RemEq; -use integer::U128PartialOrd; -use integer::U128PartialEq; -use integer::U128BitAnd; -use integer::U128BitOr; -use integer::U128BitXor; use integer::u128_is_zero; use integer::u8; use integer::u8_const; -use integer::U8Add; -use integer::U8Sub; -use integer::U8Mul; -use integer::U8Div; -use integer::U8Rem; -use integer::U8AddEq; -use integer::U8SubEq; -use integer::U8MulEq; -use integer::U8DivEq; -use integer::U8RemEq; -use integer::U8PartialEq; -use integer::U8PartialOrd; use integer::u16; use integer::u16_const; -use integer::U16Add; -use integer::U16Sub; -use integer::U16Mul; -use integer::U16Div; -use integer::U16Rem; -use integer::U16AddEq; -use integer::U16SubEq; -use integer::U16MulEq; -use integer::U16DivEq; -use integer::U16RemEq; -use integer::U16PartialEq; -use integer::U16PartialOrd; use integer::u32; use integer::u32_const; -use integer::U32Add; -use integer::U32Sub; -use integer::U32Mul; -use integer::U32Div; -use integer::U32Rem; -use integer::U32AddEq; -use integer::U32SubEq; -use integer::U32MulEq; -use integer::U32DivEq; -use integer::U32RemEq; -use integer::U32PartialEq; -use integer::U32PartialOrd; use integer::u64; use integer::u64_const; -use integer::U64Add; -use integer::U64Sub; -use integer::U64Mul; -use integer::U64Div; -use integer::U64Rem; -use integer::U64AddEq; -use integer::U64SubEq; -use integer::U64MulEq; -use integer::U64DivEq; -use integer::U64RemEq; -use integer::U64PartialEq; -use integer::U64PartialOrd; use integer::u256; -use integer::U256Add; -use integer::U256Sub; -use integer::U256Mul; -use integer::U256AddEq; -use integer::U256SubEq; -use integer::U256MulEq; -use integer::U256PartialOrd; -use integer::U256PartialEq; -use integer::U256BitAnd; -use integer::U256BitOr; -use integer::U256BitXor; use integer::Felt252TryIntoU8; use integer::U8IntoFelt252; use integer::Felt252TryIntoU16; @@ -375,11 +290,16 @@ enum PanicResult { enum never {} extern fn panic(data: Array) -> never; +#[inline(always)] +fn panic_with_felt252(err_code: felt252) -> never { + let mut data = ArrayTrait::new(); + data.append(err_code); + panic(data) +} + fn assert(cond: bool, err_code: felt252) { if !cond { - let mut data = ArrayTrait::new(); - data.append(err_code); - panic(data); + panic_with_felt252(err_code) } } @@ -391,6 +311,10 @@ mod hash; use hash::pedersen; use hash::Pedersen; +// Poseidon +mod poseidon; +use poseidon::Poseidon; + // Debug. mod debug; @@ -401,51 +325,13 @@ use starknet::System; // Internals. mod internal; +// Zeroable. mod zeroable; use zeroable::Zeroable; +use zeroable::NonZero; #[cfg(test)] mod test; // Module for testing only. mod testing; - -// Tuple Copy and Drop impls. -impl TupleSize0Copy of Copy::<()>; -impl TupleSize0Drop of Drop::<()>; - -impl TupleSize1Copy> of Copy::<(E0, )>; -impl TupleSize1Drop> of Drop::<(E0, )>; - -impl TupleSize2Copy, impl E1Copy: Copy::> of Copy::<(E0, E1)>; -impl TupleSize2Drop, impl E1Drop: Drop::> of Drop::<(E0, E1)>; - -impl TupleSize3Copy, -impl E1Copy: Copy::, -impl E2Copy: Copy::> of Copy::<(E0, E1, E2)>; -impl TupleSize3Drop, -impl E1Drop: Drop::, -impl E2Drop: Drop::> of Drop::<(E0, E1, E2)>; - -impl TupleSize4Copy, -impl E1Copy: Copy::, -impl E2Copy: Copy::, -impl E3Copy: Copy::> of Copy::<(E0, E1, E2, E3)>; -impl TupleSize4Drop, -impl E1Drop: Drop::, -impl E2Drop: Drop::, -impl E2Drop: Drop::> of Drop::<(E0, E1, E2, E3)>; diff --git a/corelib/src/nullable.cairo b/corelib/src/nullable.cairo index 6beaad2ff..98cfd7b9b 100644 --- a/corelib/src/nullable.cairo +++ b/corelib/src/nullable.cairo @@ -1,3 +1,6 @@ +use traits::Default; +use traits::Felt252DictValue; + extern type Nullable; enum FromNullableResult { @@ -10,5 +13,19 @@ extern fn nullable_from_box(value: Box) -> Nullable nopanic; extern fn match_nullable(value: Nullable) -> FromNullableResult nopanic; // Impls for generic types -impl NullableCopy> of Copy::>; -impl NullableDrop> of Drop::>; +impl NullableCopy> of Copy>; +impl NullableDrop> of Drop>; + +impl NullableDefault of Default> { + #[inline(always)] + fn default() -> Nullable nopanic { + null() + } +} + +impl NullableFelt252DictValue of Felt252DictValue> { + #[inline(always)] + fn zero_default() -> Nullable nopanic { + null() + } +} diff --git a/corelib/src/option.cairo b/corelib/src/option.cairo index 244d507b3..fc282f215 100644 --- a/corelib/src/option.cairo +++ b/corelib/src/option.cairo @@ -14,26 +14,26 @@ trait OptionTrait { /// Returns `true` if the `Option` is `Option::None`. fn is_none(self: @Option) -> bool; } -impl OptionTraitImpl of OptionTrait:: { +impl OptionTraitImpl of OptionTrait { + #[inline(always)] fn expect(self: Option, err: felt252) -> T { match self { Option::Some(x) => x, - Option::None(()) => { - let mut data = ArrayTrait::new(); - data.append(err); - panic(data) - }, + Option::None(_) => panic_with_felt252(err), } } + #[inline(always)] fn unwrap(self: Option) -> T { self.expect('Option::unwrap failed.') } + #[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, @@ -43,5 +43,5 @@ impl OptionTraitImpl of OptionTrait:: { } // Impls for generic types. -impl OptionCopy> of Copy::>; -impl OptionDrop> of Drop::>; +impl OptionCopy> of Copy>; +impl OptionDrop> of Drop>; diff --git a/corelib/src/poseidon.cairo b/corelib/src/poseidon.cairo new file mode 100644 index 000000000..b1ab40d95 --- /dev/null +++ b/corelib/src/poseidon.cairo @@ -0,0 +1,56 @@ +use array::Span; +use array::SpanTrait; +use option::OptionTrait; + +extern type Poseidon; + +extern fn hades_permutation( + s0: felt252, s1: felt252, s2: felt252 +) -> (felt252, felt252, felt252) implicits(Poseidon) nopanic; + + +// Represents a Poseidon state. +#[derive(Copy, Drop)] +struct PoseidonBuiltinState { + s0: felt252, + s1: felt252, + s2: felt252, +} + + +/// 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. +fn poseidon_hash_span(mut span: Span) -> felt252 { + let builtin_costs = get_builtin_costs(); + _poseidon_hash_span_inner(builtin_costs, PoseidonBuiltinState { s0: 0, s1: 0, s2: 0 }, ref span) +} + +/// Helper function for poseidon_hash_span. +fn _poseidon_hash_span_inner( + builtin_costs: gas::BuiltinCosts, state: PoseidonBuiltinState, ref span: Span +) -> felt252 { + let x = match span.pop_front() { + Option::Some(x) => x, + Option::None(()) => { + // Pad input with [1, 0]. + let (s0, s1, s2) = hades_permutation(state.s0 + 1, state.s1, state.s2); + return s0; + }, + }; + let y = match span.pop_front() { + Option::Some(y) => y, + Option::None(()) => { + // Add x and pad with [0]. + let (s0, s1, s2) = hades_permutation(state.s0 + *x, state.s1 + 1, state.s2); + return s0; + }, + }; + + let (s0, s1, s2) = hades_permutation(state.s0 + *x, state.s1 + *y, state.s2); + gas::withdraw_gas_all(builtin_costs).expect('Out of gas'); + _poseidon_hash_span_inner(builtin_costs, PoseidonBuiltinState { s0, s1, s2 }, ref span) +} diff --git a/corelib/src/result.cairo b/corelib/src/result.cairo index 7ba0e0cbd..d0db3f497 100644 --- a/corelib/src/result.cairo +++ b/corelib/src/result.cairo @@ -5,43 +5,35 @@ enum Result { } trait ResultTrait { /// If `val` is `Result::Ok(x)`, returns `x`. Otherwise, panics with `err`. - fn expect>(self: Result, err: felt252) -> T; + fn expect>(self: Result, err: felt252) -> T; /// If `val` is `Result::Ok(x)`, returns `x`. Otherwise, panics. - fn unwrap>(self: Result) -> T; + fn unwrap>(self: Result) -> T; /// If `val` is `Result::Err(x)`, returns `x`. Otherwise, panics with `err`. - fn expect_err>(self: Result, err: felt252) -> E; + fn expect_err>(self: Result, err: felt252) -> E; /// If `val` is `Result::Err(x)`, returns `x`. Otherwise, panics. - fn unwrap_err>(self: Result) -> E; + fn unwrap_err>(self: Result) -> E; /// Returns `true` if the `Result` is `Result::Ok`. fn is_ok(self: @Result) -> bool; /// Returns `true` if the `Result` is `Result::Err`. fn is_err(self: @Result) -> bool; } -impl ResultTraitImpl of ResultTrait:: { - fn expect>(self: Result, err: felt252) -> T { +impl ResultTraitImpl of ResultTrait { + fn expect>(self: Result, err: felt252) -> T { match self { Result::Ok(x) => x, - Result::Err(_) => { - let mut data = ArrayTrait::new(); - data.append(err); - panic(data) - }, + Result::Err(_) => panic_with_felt252(err), } } - fn unwrap>(self: Result) -> T { + fn unwrap>(self: Result) -> T { self.expect('Result::unwrap failed.') } - fn expect_err>(self: Result, err: felt252) -> E { + fn expect_err>(self: Result, err: felt252) -> E { match self { - Result::Ok(_) => { - let mut data = ArrayTrait::new(); - data.append(err); - panic(data) - }, + Result::Ok(_) => panic_with_felt252(err), Result::Err(x) => x, } } - fn unwrap_err>(self: Result) -> E { + fn unwrap_err>(self: Result) -> E { self.expect_err('Result::unwrap_err failed.') } fn is_ok(self: @Result) -> bool { @@ -59,5 +51,5 @@ impl ResultTraitImpl of ResultTrait:: { } // Impls for generic types. -impl ResultCopy, impl ECopy: Copy::> of Copy::>; -impl ResultDrop, impl EDrop: Drop::> of Drop::>; +impl ResultCopy, impl ECopy: Copy> of Copy>; +impl ResultDrop, impl EDrop: Drop> of Drop>; diff --git a/corelib/src/serde.cairo b/corelib/src/serde.cairo index 432e687fb..4f3594f8c 100644 --- a/corelib/src/serde.cairo +++ b/corelib/src/serde.cairo @@ -4,22 +4,22 @@ use traits::Into; use traits::TryInto; trait Serde { - fn serialize(ref serialized: Array, input: T); + fn serialize(ref output: Array, input: T); fn deserialize(ref serialized: Span) -> Option; } -impl Felt252Serde of Serde:: { - fn serialize(ref serialized: Array, input: felt252) { - serialized.append(input); +impl Felt252Serde of Serde { + fn serialize(ref output: Array, input: felt252) { + output.append(input); } fn deserialize(ref serialized: Span) -> Option { Option::Some(*serialized.pop_front()?) } } -impl BoolSerde of Serde:: { - fn serialize(ref serialized: Array, input: bool) { - Serde::::serialize(ref serialized, if input { +impl BoolSerde of Serde { + fn serialize(ref output: Array, input: bool) { + Serde::::serialize(ref output, if input { 1 } else { 0 @@ -30,70 +30,55 @@ impl BoolSerde of Serde:: { } } -impl U8Serde of Serde:: { - fn serialize(ref serialized: Array, input: u8) { - Serde::::serialize(ref serialized, input.into()); +impl U8Serde of Serde { + fn serialize(ref output: Array, input: u8) { + Serde::::serialize(ref output, input.into()); } fn deserialize(ref serialized: Span) -> Option { Option::Some(((*serialized.pop_front()?).try_into())?) } } -impl U16Serde of Serde:: { - fn serialize(ref serialized: Array, input: u16) { - Serde::::serialize(ref serialized, input.into()); +impl U16Serde of Serde { + fn serialize(ref output: Array, input: u16) { + Serde::::serialize(ref output, input.into()); } fn deserialize(ref serialized: Span) -> Option { Option::Some(((*serialized.pop_front()?).try_into())?) } } -impl U32Serde of Serde:: { - fn serialize(ref serialized: Array, input: u32) { - Serde::::serialize(ref serialized, input.into()); +impl U32Serde of Serde { + fn serialize(ref output: Array, input: u32) { + Serde::::serialize(ref output, input.into()); } fn deserialize(ref serialized: Span) -> Option { Option::Some(((*serialized.pop_front()?).try_into())?) } } -impl U64Serde of Serde:: { - fn serialize(ref serialized: Array, input: u64) { - Serde::::serialize(ref serialized, input.into()); +impl U64Serde of Serde { + fn serialize(ref output: Array, input: u64) { + Serde::::serialize(ref output, input.into()); } fn deserialize(ref serialized: Span) -> Option { Option::Some(((*serialized.pop_front()?).try_into())?) } } -impl U128Serde of Serde:: { - fn serialize(ref serialized: Array, input: u128) { - Serde::::serialize(ref serialized, input.into()); +impl U128Serde of Serde { + fn serialize(ref output: Array, input: u128) { + Serde::::serialize(ref output, input.into()); } fn deserialize(ref serialized: Span) -> Option { Option::Some(((*serialized.pop_front()?).try_into())?) } } -impl U256Serde of Serde:: { - fn serialize(ref serialized: Array, input: u256) { - Serde::::serialize(ref serialized, input.low); - Serde::::serialize(ref serialized, input.high); - } - fn deserialize(ref serialized: Span) -> Option { - Option::Some( - u256 { - low: Serde::::deserialize(ref serialized)?, - high: Serde::::deserialize(ref serialized)?, - } - ) - } -} - -impl ArraySerde, impl TDrop: Drop::> of Serde::> { - fn serialize(ref serialized: Array, mut input: Array) { - Serde::::serialize(ref serialized, input.len()); - serialize_array_helper(ref serialized, input); +impl ArraySerde, impl TDrop: Drop> of Serde> { + fn serialize(ref output: Array, mut input: Array) { + Serde::::serialize(ref output, input.len()); + serialize_array_helper(ref output, input); } fn deserialize(ref serialized: Span) -> Option> { let length = *serialized.pop_front()?; @@ -102,39 +87,21 @@ impl ArraySerde, impl TDrop: Drop::> of Serde::, impl TDrop: Drop::>( - ref serialized: Array, mut input: Array +fn serialize_array_helper, impl TDrop: Drop>( + ref output: Array, mut input: Array ) { - // TODO(orizi): Replace with simple call once inlining is supported. - match gas::withdraw_gas() { - Option::Some(_) => {}, - Option::None(_) => { - let mut data = ArrayTrait::new(); - data.append('Out of gas'); - panic(data); - }, - } match input.pop_front() { Option::Some(value) => { - TSerde::serialize(ref serialized, value); - serialize_array_helper(ref serialized, input); + TSerde::serialize(ref output, value); + serialize_array_helper(ref output, input); }, Option::None(_) => {}, } } -fn deserialize_array_helper, impl TDrop: Drop::>( +fn deserialize_array_helper, impl TDrop: Drop>( ref serialized: Span, mut curr_output: Array, remaining: felt252 ) -> Option> { - // TODO(orizi): Replace with simple call once inlining is supported. - match gas::withdraw_gas() { - Option::Some(_) => {}, - Option::None(_) => { - let mut data = ArrayTrait::new(); - data.append('Out of gas'); - panic(data); - }, - } if remaining == 0 { return Option::Some(curr_output); } @@ -142,17 +109,17 @@ fn deserialize_array_helper, impl TDrop: Drop::>( deserialize_array_helper(ref serialized, curr_output, remaining - 1) } -impl TupleSize0Serde of Serde::<()> { - fn serialize(ref serialized: Array, mut input: ()) {} +impl TupleSize0Serde of Serde<()> { + fn serialize(ref output: Array, mut input: ()) {} fn deserialize(ref serialized: Span) -> Option<()> { Option::Some(()) } } -impl TupleSize1Serde> of Serde::<(E0, )> { - fn serialize(ref serialized: Array, mut input: (E0, )) { +impl TupleSize1Serde> of Serde<(E0, )> { + fn serialize(ref output: Array, mut input: (E0, )) { let (e0, ) = input; - E0Serde::serialize(ref serialized, e0) + E0Serde::serialize(ref output, e0) } fn deserialize(ref serialized: Span) -> Option<(E0, )> { Option::Some((E0Serde::deserialize(ref serialized)?, )) @@ -161,13 +128,14 @@ impl TupleSize1Serde> of Serde::<(E0, )> { impl TupleSize2Serde, -impl E0Drop: Drop::, -impl E1Serde: Serde::> of Serde::<(E0, E1)> { - fn serialize(ref serialized: Array, mut input: (E0, E1)) { +impl E0Serde: Serde, +impl E0Drop: Drop, +impl E1Serde: Serde, +impl E0Drop: Drop> of Serde<(E0, E1)> { + fn serialize(ref output: Array, mut input: (E0, E1)) { let (e0, e1) = input; - E0Serde::serialize(ref serialized, e0); - E1Serde::serialize(ref serialized, e1) + E0Serde::serialize(ref output, e0); + E1Serde::serialize(ref output, e1) } fn deserialize(ref serialized: Span) -> Option<(E0, E1)> { Option::Some((E0Serde::deserialize(ref serialized)?, E1Serde::deserialize(ref serialized)?)) @@ -177,16 +145,17 @@ impl E1Serde: Serde::> of Serde::<(E0, E1)> { impl TupleSize3Serde, -impl E0Drop: Drop::, -impl E1Serde: Serde::, -impl E1Drop: Drop::, -impl E2Serde: Serde::> of Serde::<(E0, E1, E2)> { - fn serialize(ref serialized: Array, mut input: (E0, E1, E2)) { +impl E0Serde: Serde, +impl E0Drop: Drop, +impl E1Serde: Serde, +impl E1Drop: Drop, +impl E2Serde: Serde, +impl E2Drop: Drop> of Serde<(E0, E1, E2)> { + fn serialize(ref output: Array, mut input: (E0, E1, E2)) { let (e0, e1, e2) = input; - E0Serde::serialize(ref serialized, e0); - E1Serde::serialize(ref serialized, e1); - E2Serde::serialize(ref serialized, e2) + E0Serde::serialize(ref output, e0); + E1Serde::serialize(ref output, e1); + E2Serde::serialize(ref output, e2) } fn deserialize(ref serialized: Span) -> Option<(E0, E1, E2)> { Option::Some( @@ -203,19 +172,20 @@ impl TupleSize4Serde, -impl E0Drop: Drop::, -impl E1Serde: Serde::, -impl E1Drop: Drop::, -impl E2Serde: Serde::, -impl E2Drop: Drop::, -impl E3Serde: Serde::> of Serde::<(E0, E1, E2, E3)> { - fn serialize(ref serialized: Array, mut input: (E0, E1, E2, E3)) { +impl E0Serde: Serde, +impl E0Drop: Drop, +impl E1Serde: Serde, +impl E1Drop: Drop, +impl E2Serde: Serde, +impl E2Drop: Drop, +impl E3Serde: Serde, +impl E3Drop: Drop> of Serde<(E0, E1, E2, E3)> { + fn serialize(ref output: Array, mut input: (E0, E1, E2, E3)) { let (e0, e1, e2, e3) = input; - E0Serde::serialize(ref serialized, e0); - E1Serde::serialize(ref serialized, e1); - E2Serde::serialize(ref serialized, e2); - E3Serde::serialize(ref serialized, e3) + E0Serde::serialize(ref output, e0); + E1Serde::serialize(ref output, e1); + E2Serde::serialize(ref output, e2); + E3Serde::serialize(ref output, e3) } fn deserialize(ref serialized: Span) -> Option<(E0, E1, E2, E3)> { Option::Some( @@ -228,4 +198,3 @@ impl E3Serde: Serde::> of Serde::<(E0, E1, E2, E3)> { ) } } - diff --git a/corelib/src/starknet.cairo b/corelib/src/starknet.cairo index 67373760b..cb999e0cb 100644 --- a/corelib/src/starknet.cairo +++ b/corelib/src/starknet.cairo @@ -31,7 +31,6 @@ use contract_address::Felt252TryIntoContractAddress; use contract_address::contract_address_const; use contract_address::contract_address_to_felt252; use contract_address::contract_address_try_from_felt252; -use contract_address::ContractAddressZeroable; // ContractAddress mod class_hash; @@ -39,7 +38,6 @@ use class_hash::ClassHash; use class_hash::ClassHashIntoFelt252; use class_hash::Felt252TryIntoClassHash; use class_hash::class_hash_const; -use class_hash::ClassHashZeroable; mod info; use info::ExecutionInfo; @@ -50,6 +48,10 @@ use info::get_caller_address; use info::get_contract_address; use info::get_block_info; use info::get_tx_info; +use info::get_block_timestamp; + +mod event; +use event::Event; extern type System; @@ -63,13 +65,11 @@ 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:: { +impl SyscallResultTraitImpl of SyscallResultTrait { fn unwrap_syscall(self: SyscallResult) -> T { match self { Result::Ok(x) => x, - Result::Err(revert_reason) => { - panic(revert_reason) - }, + Result::Err(revert_reason) => panic(revert_reason), } } } diff --git a/corelib/src/starknet/class_hash.cairo b/corelib/src/starknet/class_hash.cairo index 10b1da56b..6e6242ffd 100644 --- a/corelib/src/starknet/class_hash.cairo +++ b/corelib/src/starknet/class_hash.cairo @@ -4,25 +4,25 @@ use zeroable::Zeroable; extern type ClassHash; -extern fn class_hash_const() -> ClassHash nopanic; +extern fn class_hash_const() -> ClassHash nopanic; extern fn class_hash_to_felt252(address: ClassHash) -> felt252 nopanic; extern fn class_hash_try_from_felt252( address: felt252 ) -> Option implicits(RangeCheck) nopanic; -impl Felt252TryIntoClassHash of TryInto:: { +impl Felt252TryIntoClassHash of TryInto { fn try_into(self: felt252) -> Option { class_hash_try_from_felt252(self) } } -impl ClassHashIntoFelt252 of Into:: { +impl ClassHashIntoFelt252 of Into { fn into(self: ClassHash) -> felt252 { class_hash_to_felt252(self) } } -impl ClassHashZeroable of Zeroable:: { +impl ClassHashZeroable of Zeroable { fn zero() -> ClassHash { class_hash_const::<0>() } @@ -38,22 +38,24 @@ impl ClassHashZeroable of Zeroable:: { } } -impl ClassHashSerde of serde::Serde:: { - fn serialize(ref serialized: Array, input: ClassHash) { - serde::Serde::serialize(ref serialized, class_hash_to_felt252(input)); +impl ClassHashSerde of serde::Serde { + fn serialize(ref output: Array, input: ClassHash) { + serde::Serde::serialize(ref output, class_hash_to_felt252(input)); } fn deserialize(ref serialized: Span) -> Option { - Option::Some(class_hash_try_from_felt252(serde::Serde::deserialize(ref serialized)?)?) + Option::Some( + class_hash_try_from_felt252(serde::Serde::::deserialize(ref serialized)?)? + ) } } -impl ClassHashPartialEq of PartialEq:: { +impl ClassHashPartialEq of PartialEq { #[inline(always)] - fn eq(a: ClassHash, b: ClassHash) -> bool { - class_hash_to_felt252(a) == class_hash_to_felt252(b) + fn eq(lhs: ClassHash, rhs: ClassHash) -> bool { + class_hash_to_felt252(lhs) == class_hash_to_felt252(rhs) } #[inline(always)] - fn ne(a: ClassHash, b: ClassHash) -> bool { - !(a == b) + fn ne(lhs: ClassHash, rhs: ClassHash) -> bool { + !(lhs == rhs) } } diff --git a/corelib/src/starknet/contract_address.cairo b/corelib/src/starknet/contract_address.cairo index 6c7eb2bff..2098de563 100644 --- a/corelib/src/starknet/contract_address.cairo +++ b/corelib/src/starknet/contract_address.cairo @@ -4,25 +4,25 @@ use zeroable::Zeroable; extern type ContractAddress; -extern fn contract_address_const() -> ContractAddress nopanic; +extern fn contract_address_const() -> ContractAddress nopanic; extern fn contract_address_to_felt252(address: ContractAddress) -> felt252 nopanic; extern fn contract_address_try_from_felt252( address: felt252 ) -> Option implicits(RangeCheck) nopanic; -impl Felt252TryIntoContractAddress of TryInto:: { +impl Felt252TryIntoContractAddress of TryInto { fn try_into(self: felt252) -> Option { contract_address_try_from_felt252(self) } } -impl ContractAddressIntoFelt252 of Into:: { +impl ContractAddressIntoFelt252 of Into { fn into(self: ContractAddress) -> felt252 { contract_address_to_felt252(self) } } -impl ContractAddressZeroable of Zeroable:: { +impl ContractAddressZeroable of Zeroable { fn zero() -> ContractAddress { contract_address_const::<0>() } @@ -38,22 +38,26 @@ impl ContractAddressZeroable of Zeroable:: { } } -impl ContractAddressSerde of serde::Serde:: { - fn serialize(ref serialized: Array, input: ContractAddress) { - serde::Serde::serialize(ref serialized, contract_address_to_felt252(input)); +impl ContractAddressSerde of serde::Serde { + fn serialize(ref output: Array, input: ContractAddress) { + serde::Serde::serialize(ref output, contract_address_to_felt252(input)); } fn deserialize(ref serialized: Span) -> Option { - Option::Some(contract_address_try_from_felt252(serde::Serde::deserialize(ref serialized)?)?) + Option::Some( + contract_address_try_from_felt252( + serde::Serde::::deserialize(ref serialized)? + )? + ) } } -impl ContractAddressPartialEq of PartialEq:: { +impl ContractAddressPartialEq of PartialEq { #[inline(always)] - fn eq(a: ContractAddress, b: ContractAddress) -> bool { - contract_address_to_felt252(a) == contract_address_to_felt252(b) + fn eq(lhs: ContractAddress, rhs: ContractAddress) -> bool { + contract_address_to_felt252(lhs) == contract_address_to_felt252(rhs) } #[inline(always)] - fn ne(a: ContractAddress, b: ContractAddress) -> bool { - !(a == b) + fn ne(lhs: ContractAddress, rhs: ContractAddress) -> bool { + !(lhs == rhs) } } diff --git a/corelib/src/starknet/event.cairo b/corelib/src/starknet/event.cairo new file mode 100644 index 000000000..f15ee615b --- /dev/null +++ b/corelib/src/starknet/event.cairo @@ -0,0 +1,13 @@ +use serde::Serde; + +trait Event { + // TODO(spapini): Add a "deserialize" function meant for viewing the event. + fn append_keys_and_values(self: T, ref keys: Array, ref values: Array); +} + +impl EventForSerde> of Event { + fn append_keys_and_values(self: T, ref keys: Array, ref values: Array) { + Serde::serialize(ref values, self) + } +} + diff --git a/corelib/src/starknet/info.cairo b/corelib/src/starknet/info.cairo index 47df78db1..4c6447991 100644 --- a/corelib/src/starknet/info.cairo +++ b/corelib/src/starknet/info.cairo @@ -61,3 +61,7 @@ fn get_block_info() -> Box { fn get_tx_info() -> Box { get_execution_info().unbox().tx_info } + +fn get_block_timestamp() -> u64 { + get_block_info().unbox().block_timestamp +} diff --git a/corelib/src/starknet/storage_access.cairo b/corelib/src/starknet/storage_access.cairo index 34d3fc2c9..3a5f547f4 100644 --- a/corelib/src/starknet/storage_access.cairo +++ b/corelib/src/starknet/storage_access.cairo @@ -18,7 +18,7 @@ extern type StorageAddress; extern type StorageBaseAddress; // Storage. -extern fn storage_base_address_const() -> StorageBaseAddress nopanic; +extern fn storage_base_address_const() -> StorageBaseAddress nopanic; extern fn storage_base_address_from_felt252( addr: felt252 ) -> StorageBaseAddress implicits(RangeCheck) nopanic; @@ -34,23 +34,25 @@ extern fn storage_address_try_from_felt252( address: felt252 ) -> Option implicits(RangeCheck) nopanic; -impl Felt252TryIntoStorageAddress of TryInto:: { +impl Felt252TryIntoStorageAddress of TryInto { fn try_into(self: felt252) -> Option { storage_address_try_from_felt252(self) } } -impl StorageAddressIntoFelt252 of Into:: { +impl StorageAddressIntoFelt252 of Into { fn into(self: StorageAddress) -> felt252 { storage_address_to_felt252(self) } } -impl StorageAddressSerde of serde::Serde:: { - fn serialize(ref serialized: Array, input: StorageAddress) { - serde::Serde::serialize(ref serialized, storage_address_to_felt252(input)); +impl StorageAddressSerde of serde::Serde { + fn serialize(ref output: Array, input: StorageAddress) { + serde::Serde::serialize(ref output, storage_address_to_felt252(input)); } fn deserialize(ref serialized: Span) -> Option { - Option::Some(storage_address_try_from_felt252(serde::Serde::deserialize(ref serialized)?)?) + Option::Some( + storage_address_try_from_felt252(serde::Serde::::deserialize(ref serialized)?)? + ) } } @@ -59,7 +61,7 @@ trait StorageAccess { fn write(address_domain: u32, base: StorageBaseAddress, value: T) -> SyscallResult<()>; } -impl StorageAccessFelt252 of StorageAccess:: { +impl StorageAccessFelt252 of StorageAccess { #[inline(always)] fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult { storage_read_syscall(address_domain, storage_address_from_base(base)) @@ -70,7 +72,7 @@ impl StorageAccessFelt252 of StorageAccess:: { } } -impl StorageAccessBool of StorageAccess:: { +impl StorageAccessBool of StorageAccess { fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult { Result::Ok(StorageAccess::::read(address_domain, base)? != 0) } @@ -84,7 +86,7 @@ impl StorageAccessBool of StorageAccess:: { } } -impl StorageAccessU8 of StorageAccess:: { +impl StorageAccessU8 of StorageAccess { fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult { Result::Ok( StorageAccess::::read( @@ -98,7 +100,7 @@ impl StorageAccessU8 of StorageAccess:: { } } -impl StorageAccessU16 of StorageAccess:: { +impl StorageAccessU16 of StorageAccess { fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult { Result::Ok( StorageAccess::::read( @@ -112,7 +114,7 @@ impl StorageAccessU16 of StorageAccess:: { } } -impl StorageAccessU32 of StorageAccess:: { +impl StorageAccessU32 of StorageAccess { fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult { Result::Ok( StorageAccess::::read( @@ -126,7 +128,7 @@ impl StorageAccessU32 of StorageAccess:: { } } -impl StorageAccessU64 of StorageAccess:: { +impl StorageAccessU64 of StorageAccess { fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult { Result::Ok( StorageAccess::::read( @@ -140,7 +142,7 @@ impl StorageAccessU64 of StorageAccess:: { } } -impl StorageAccessU128 of StorageAccess:: { +impl StorageAccessU128 of StorageAccess { fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult { Result::Ok( StorageAccess::::read( @@ -154,7 +156,7 @@ impl StorageAccessU128 of StorageAccess:: { } } -impl StorageAccessU256 of StorageAccess:: { +impl StorageAccessU256 of StorageAccess { fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult { Result::Ok( u256 { @@ -173,7 +175,7 @@ impl StorageAccessU256 of StorageAccess:: { } } -impl StorageAccessStorageAddress of StorageAccess:: { +impl StorageAccessStorageAddress of StorageAccess { fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult { Result::Ok( StorageAccess::::read( @@ -189,7 +191,7 @@ impl StorageAccessStorageAddress of StorageAccess:: { } } -impl StorageAccessContractAddress of StorageAccess:: { +impl StorageAccessContractAddress of StorageAccess { fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult { Result::Ok( StorageAccess::::read( @@ -205,7 +207,7 @@ impl StorageAccessContractAddress of StorageAccess:: { } } -impl StorageAccessClassHash of StorageAccess:: { +impl StorageAccessClassHash of StorageAccess { fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult { Result::Ok( StorageAccess::::read(address_domain, base)?.try_into().expect('Non ClassHash') diff --git a/corelib/src/starknet/syscalls.cairo b/corelib/src/starknet/syscalls.cairo index 37fb2f863..099bbe81b 100644 --- a/corelib/src/starknet/syscalls.cairo +++ b/corelib/src/starknet/syscalls.cairo @@ -22,7 +22,7 @@ extern fn deploy_syscall( contract_address_salt: felt252, calldata: Span, deploy_from_zero: bool, -) -> SyscallResult<(ContractAddress, Span::)> implicits(GasBuiltin, System) nopanic; +) -> SyscallResult<(ContractAddress, Span)> implicits(GasBuiltin, System) nopanic; // Emits an event. // `keys` - The keys of the event. diff --git a/corelib/src/test.cairo b/corelib/src/test.cairo index f2d484f18..e51c15769 100644 --- a/corelib/src/test.cairo +++ b/corelib/src/test.cairo @@ -1,914 +1,10 @@ -use array::ArrayTrait; -use array::SpanTrait; -use dict::Felt252DictTrait; -use option::OptionTrait; -use option::OptionTraitImpl; -use core::ec; -use core::traits::TryInto; -use core::traits::Into; -use box::BoxTrait; - - -#[test] -#[should_panic(expected = ('assert(false)', ))] -fn test_assert_false() { - assert(false, 'assert(false)'); -} - -#[test] -fn test_assert_true() { - assert(true, 'assert(true)'); -} - -#[test] -fn test_bool_operators() { - assert(true == true, 't == t'); - assert(false == false, 'f == f'); - assert(!true == false, '!t == f'); - assert(!false == true, '!f == t'); - assert(true != false, 't != f'); - assert(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_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 = ec_point_from_x(1).unwrap(); - let p_nz = ec_point_non_zero(p); - let (x, y) = ec_point_unwrap(p_nz); - assert(x == 1, 'x != 1'); - assert(y == beta_p2_root | y == -beta_p2_root, 'y is wrong'); - - let mut state = ec_state_init(); - ec_state_add(ref state, p_nz); - let q = ec_state_try_finalize_nz(state).expect('zero point'); - let (qx, qy) = ec_point_unwrap(q); - assert(qx == x, 'bad finalize x'); - assert(qy == y, 'bad finalize y'); - - // Try doing the same thing with the EC op builtin. - let mut state = ec_state_init(); - ec_state_add_mul(ref state, 1, p_nz); - let q3 = ec_state_try_finalize_nz(state).expect('zero point'); - let (qx, qy) = ec_point_unwrap(q3); - assert(qx == x, 'bad EC op x'); - assert(qy == y, 'bad EC op y'); - - // Try computing `p + p` using the ec_mul function. - let double_p = ec_mul(p, 2); - let (double_x, double_y) = ec_point_unwrap(ec_point_non_zero(double_p)); - let expected_double_y = - 3572434102142093425782752266058856056057826477682467661647843687948039943621; - assert( - 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) = ec_point_unwrap(ec_point_non_zero(double_p - p)); - assert(sub_x == x, 'bad x for 2p - p'); - assert(sub_y == y, 'bad y for 2p - p'); - - // Compute `p - p`. - assert(ec_point_is_zero(p - p).into(), 'p - p did not return 0.'); - - // Compute `(-p) - p`. - let (sub2_x, sub2_y) = ec_point_unwrap(ec_point_non_zero(ec_neg(p) - p)); - assert(sub2_x == double_x, 'bad x for (-p) - p'); - assert(sub2_y == -double_y, 'bad y for (-p) - p'); -} - -#[test] -#[should_panic] -fn test_bad_ec_point_creation() { - ec_point_new(0, 0); -} - -#[test] -fn test_ec_point_finalization_zero() { - let state = ec_state_init(); - let point_at_infinity = ec_state_try_finalize_nz(state); - 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_ec_mul() { - let p = ec_point_new( - x: 336742005567258698661916498343089167447076063081786685068305785816009957563, - y: 1706004133033694959518200210163451614294041810778629639790706933324248611779, - ); - let m = 2713877091499598330239944961141122840311015265600950719674787125185463975936; - let (x, y) = ec_point_unwrap(ec_point_non_zero(ec_mul(p, m))); - - assert( - x == 2881632108168892236043523177391659237686965655035240771134509747985978822780, - 'ec_mul failed (x).' - ); - assert( - y == 591135563672138037839394207500885413019058613584891498394077262936524140839, - 'ec_mul failed (y).' - ); -} - -#[test] -fn test_felt252_operators() { - assert(1 + 3 == 4, '1 + 3 == 4'); - assert(3 + 6 == 9, '3 + 6 == 9'); - assert(3 - 1 == 2, '3 - 1 == 2'); - assert(1231 - 231 == 1000, '1231-231=1000'); - assert(1 * 3 == 3, '1 * 3 == 3'); - assert(3 * 6 == 18, '3 * 6 == 18'); - assert(-3 == 1 - 4, '-3 == 1 - 4'); -} - -#[test] -fn test_u8_operators() { - assert(1_u8 == 1_u8, '1 == 1'); - assert(1_u8 != 2_u8, '1 != 2'); - assert(1_u8 + 3_u8 == 4_u8, '1 + 3 == 4'); - assert(3_u8 + 6_u8 == 9_u8, '3 + 6 == 9'); - assert(3_u8 - 1_u8 == 2_u8, '3 - 1 == 2'); - assert(1_u8 * 3_u8 == 3_u8, '1 * 3 == 3'); - assert(2_u8 * 4_u8 == 8_u8, '2 * 4 == 8'); - assert(19_u8 / 7_u8 == 2_u8, '19 / 7 == 2'); - assert(19_u8 % 7_u8 == 5_u8, '19 % 7 == 5'); - assert(231_u8 - 131_u8 == 100_u8, '231-131=100'); - assert(1_u8 < 4_u8, '1 < 4'); - assert(1_u8 <= 4_u8, '1 <= 4'); - assert(!(4_u8 < 4_u8), '!(4 < 4)'); - assert(4_u8 <= 4_u8, '4 <= 4'); - assert(5_u8 > 2_u8, '5 > 2'); - assert(5_u8 >= 2_u8, '5 >= 2'); - assert(!(3_u8 > 3_u8), '!(3 > 3)'); - assert(3_u8 >= 3_u8, '3 >= 3'); -} - -#[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] -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(1_u16 == 1_u16, '1 == 1'); - assert(1_u16 != 2_u16, '1 != 2'); - assert(1_u16 + 3_u16 == 4_u16, '1 + 3 == 4'); - assert(3_u16 + 6_u16 == 9_u16, '3 + 6 == 9'); - assert(3_u16 - 1_u16 == 2_u16, '3 - 1 == 2'); - assert(231_u16 - 131_u16 == 100_u16, '231-131=100'); - assert(1_u16 * 3_u16 == 3_u16, '1 * 3 == 3'); - assert(2_u16 * 4_u16 == 8_u16, '2 * 4 == 8'); - assert(51725_u16 / 7_u16 == 7389_u16, '51725 / 7 == 7389'); - assert(51725_u16 % 7_u16 == 2_u16, '51725 % 7 == 2'); - assert(1_u16 < 4_u16, '1 < 4'); - assert(1_u16 <= 4_u16, '1 <= 4'); - assert(!(4_u16 < 4_u16), '!(4 < 4)'); - assert(4_u16 <= 4_u16, '4 <= 4'); - assert(5_u16 > 2_u16, '5 > 2'); - assert(5_u16 >= 2_u16, '5 >= 2'); - assert(!(3_u16 > 3_u16), '!(3 > 3)'); - assert(3_u16 >= 3_u16, '3 >= 3'); -} - -#[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] -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(1_u32 == 1_u32, '1 == 1'); - assert(1_u32 != 2_u32, '1 != 2'); - assert(1_u32 + 3_u32 == 4_u32, '1 + 3 == 4'); - assert(3_u32 + 6_u32 == 9_u32, '3 + 6 == 9'); - assert(3_u32 - 1_u32 == 2_u32, '3 - 1 == 2'); - assert(231_u32 - 131_u32 == 100_u32, '231-131=100'); - assert(1_u32 * 3_u32 == 3_u32, '1 * 3 == 3'); - assert(2_u32 * 4_u32 == 8_u32, '2 * 4 == 8'); - assert(510670725_u32 / 7_u32 == 72952960_u32, '510670725 / 7 == 72952960'); - assert(510670725_u32 % 7_u32 == 5_u32, '510670725 % 7 == 5'); - assert(1_u32 < 4_u32, '1 < 4'); - assert(1_u32 <= 4_u32, '1 <= 4'); - assert(!(4_u32 < 4_u32), '!(4 < 4)'); - assert(4_u32 <= 4_u32, '4 <= 4'); - assert(5_u32 > 2_u32, '5 > 2'); - assert(5_u32 >= 2_u32, '5 >= 2'); - assert(!(3_u32 > 3_u32), '!(3 > 3)'); - assert(3_u32 >= 3_u32, '3 >= 3'); -} - -#[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] -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(1_u64 == 1_u64, '1 == 1'); - assert(1_u64 != 2_u64, '1 != 2'); - assert(1_u64 + 3_u64 == 4_u64, '1 + 3 == 4'); - assert(3_u64 + 6_u64 == 9_u64, '3 + 6 == 9'); - assert(3_u64 - 1_u64 == 2_u64, '3 - 1 == 2'); - assert(231_u64 - 131_u64 == 100_u64, '231-131=100'); - assert(1_u64 * 3_u64 == 3_u64, '1 * 3 == 3'); - assert(2_u64 * 4_u64 == 8_u64, '2 * 4 == 8'); - assert(5010670477878974275_u64 / 7_u64 == 715810068268424896_u64, 'Wrong division result.'); - assert(5010670477878974275_u64 % 7_u64 == 3_u64, '5010670477878974275 % 7 == 3'); - assert(1_u64 < 4_u64, '1 < 4'); - assert(1_u64 <= 4_u64, '1 <= 4'); - assert(!(4_u64 < 4_u64), '!(4 < 4)'); - assert(4_u64 <= 4_u64, '4 <= 4'); - assert(5_u64 > 2_u64, '5 > 2'); - assert(5_u64 >= 2_u64, '5 >= 2'); - assert(!(3_u64 > 3_u64), '!(3 > 3)'); - assert(3_u64 >= 3_u64, '3 >= 3'); -} - -#[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] -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(1_u128 == 1_u128, '1 == 1'); - assert(!(1_u128 == 2_u128), '!(1 == 2)'); - assert(1_u128 + 3_u128 == 4_u128, '1 + 3 == 4'); - assert(3_u128 + 6_u128 == 9_u128, '3 + 6 == 9'); - assert(3_u128 - 1_u128 == 2_u128, '3 - 1 == 2'); - assert(1231_u128 - 231_u128 == 1000_u128, '1231-231=1000'); - assert(1_u128 * 3_u128 == 3_u128, '1 * 3 == 3'); - assert(2_u128 * 4_u128 == 8_u128, '2 * 4 == 8'); - assert(8_u128 / 2_u128 == 4_u128, '8 / 2 == 4'); - assert(8_u128 % 2_u128 == 0_u128, '8 % 2 == 0'); - assert(7_u128 / 3_u128 == 2_u128, '7 / 3 == 2'); - assert(7_u128 % 3_u128 == 1_u128, '7 % 3 == 1'); - assert(1_u128 < 4_u128, '1 < 4'); - assert(1_u128 <= 4_u128, '1 <= 4'); - assert(!(4_u128 < 4_u128), '!(4 < 4)'); - assert(4_u128 <= 4_u128, '4 <= 4'); - assert(5_u128 > 2_u128, '5 > 2'); - assert(5_u128 >= 2_u128, '5 >= 2'); - assert(!(3_u128 > 3_u128), '!(3 > 3)'); - assert(3_u128 >= 3_u128, '3 >= 3'); - assert((1_u128 | 2_u128) == 3_u128, '1 | 2 == 3'); - assert((1_u128 & 2_u128) == 0_u128, '1 & 2 == 0'); - assert((1_u128 ^ 2_u128) == 3_u128, '1 ^ 2 == 3'); - assert((2_u128 | 2_u128) == 2_u128, '2 | 2 == 2'); - assert((2_u128 & 2_u128) == 2_u128, '2 & 2 == 2'); - assert((2_u128 & 3_u128) == 2_u128, '2 & 3 == 2'); - assert((3_u128 ^ 6_u128) == 5_u128, '3 ^ 6 == 5'); - assert(u128_sqrt(9_u128) == 3_u128, 'u128_sqrt(9) == 3'); - assert(u128_sqrt(10_u128) == 3_u128, 'u128_sqrt(10) == 3'); - assert( - u128_sqrt(1267650600228229401496703205376_u128) == 1125899906842624_u128, - 'u128_sqrt(2^100) == 2^50' - ); - assert( - u128_sqrt(340282366920938463463374607431768211455_u128) == 18446744073709551615_u128, - 'Wrong square root result.' - ); - assert(u128_sqrt(1_u128) == 1_u128, 'u128_sqrt(1) == 1'); - assert(u128_sqrt(0_u128) == 0_u128, 'u128_sqrt(0) == 0'); -} - -fn pow_2_127() -> u128 { - 0x80000000000000000000000000000000_u128 -} - -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] -#[should_panic] -fn test_u128_add_overflow_1() { - pow_2_127() + pow_2_127(); -} - -#[test] -#[should_panic] -fn test_u128_add_overflow_2() { - (pow_2_127() + 12_u128) + pow_2_127(); -} - -#[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 * pow_2_127(); -} - -#[test] -#[should_panic] -fn test_u128_div_by_0() { - 2_u128 / 0_u128; -} - -#[test] -#[should_panic] -fn test_u128_mod_by_0() { - 2_u128 % 0_u128; -} - -// TODO(orizi): Remove when u256 literals are supported. -fn as_u256(high: u128, low: u128) -> u256 { - u256 { low, high } -} - -#[test] -fn test_u256_from_felt252() { - assert(1.into() == as_u256(0_u128, 1_u128), 'into 1'); - assert( - (170141183460469231731687303715884105728 * 2).into() == as_u256(1_u128, 0_u128), - 'into 2**128' - ); -} - -// TODO(orizi): Use u256 literals when supported. -#[test] -fn test_u256_operators() { - let max_u128 = 0xffffffffffffffffffffffffffffffff_u128; - assert(as_u256(1_u128, 1_u128) + as_u256(3_u128, 2_u128) == as_u256(4_u128, 3_u128), 'no OF'); - assert( - as_u256(1_u128, pow_2_127()) + as_u256(3_u128, pow_2_127()) == as_u256(5_u128, 0_u128), - 'basic OF' - ); - assert(as_u256(4_u128, 3_u128) - as_u256(1_u128, 1_u128) == as_u256(3_u128, 2_u128), 'no UF'); - assert( - as_u256(5_u128, 0_u128) - as_u256(1_u128, pow_2_127()) == as_u256(3_u128, pow_2_127()), - 'basic UF' - ); - assert( - as_u256(4_u128, 3_u128) * as_u256(0_u128, 1_u128) == as_u256(4_u128, 3_u128), 'mul by 1' - ); - assert( - as_u256(4_u128, 3_u128) * as_u256(0_u128, 2_u128) == as_u256(8_u128, 6_u128), 'mul by 2' - ); - assert( - as_u256(0_u128, pow_2_127()) * as_u256(0_u128, 2_u128) == as_u256(1_u128, 0_u128), - 'basic mul OF' - ); - assert( - as_u256(0_u128, max_u128) - * as_u256(0_u128, max_u128) == as_u256(0xfffffffffffffffffffffffffffffffe_u128, 1_u128), - 'max_u128 * max_u128' - ); - assert( - as_u256(0_u128, max_u128) * as_u256(0_u128, 1_u128) == as_u256(0_u128, max_u128), - 'max_u128 * 1' - ); - assert( - as_u256(0_u128, 1_u128) * as_u256(0_u128, max_u128) == as_u256(0_u128, max_u128), - '1 * max_u128' - ); - assert( - (as_u256(1_u128, 2_u128) | as_u256(2_u128, 2_u128)) == as_u256(3_u128, 2_u128), - '1.2|2.2==3.2' - ); - assert( - (as_u256(2_u128, 1_u128) | as_u256(2_u128, 2_u128)) == as_u256(2_u128, 3_u128), - '2.1|2.2==2.3' - ); - assert( - (as_u256(2_u128, 2_u128) | as_u256(1_u128, 2_u128)) == as_u256(3_u128, 2_u128), - '2.2|1.2==3.2' - ); - assert( - (as_u256(2_u128, 2_u128) | as_u256(2_u128, 1_u128)) == as_u256(2_u128, 3_u128), - '2.2|2.1==2.3' - ); - assert( - (as_u256(1_u128, 2_u128) & as_u256(2_u128, 2_u128)) == as_u256(0_u128, 2_u128), - '1.2&2.2==0.2' - ); - assert( - (as_u256(2_u128, 1_u128) & as_u256(2_u128, 2_u128)) == as_u256(2_u128, 0_u128), - '2.1&2.2==2.0' - ); - assert( - (as_u256(2_u128, 2_u128) & as_u256(1_u128, 2_u128)) == as_u256(0_u128, 2_u128), - '2.2&1.2==0.2' - ); - assert( - (as_u256(2_u128, 2_u128) & as_u256(2_u128, 1_u128)) == as_u256(2_u128, 0_u128), - '2.2&2.1==2.0' - ); - assert( - (as_u256(1_u128, 2_u128) ^ as_u256(2_u128, 2_u128)) == as_u256(3_u128, 0_u128), - '1.2^2.2==3.0' - ); - assert( - (as_u256(2_u128, 1_u128) ^ as_u256(2_u128, 2_u128)) == as_u256(0_u128, 3_u128), - '2.1^2.2==0.3' - ); - assert( - (as_u256(2_u128, 2_u128) ^ as_u256(1_u128, 2_u128)) == as_u256(3_u128, 0_u128), - '2.2^1.2==3.0' - ); - assert( - (as_u256(2_u128, 2_u128) ^ as_u256(2_u128, 1_u128)) == as_u256(0_u128, 3_u128), - '2.2^2.1==0.3' - ); - assert(as_u256(1_u128, 2_u128) < as_u256(2_u128, 2_u128), '1.2<2.2'); - assert(as_u256(2_u128, 1_u128) < as_u256(2_u128, 2_u128), '2.1<2.2'); - assert(!(as_u256(2_u128, 2_u128) < as_u256(1_u128, 2_u128)), '2.2<1.2'); - assert(!(as_u256(2_u128, 2_u128) < as_u256(2_u128, 1_u128)), '2.2<2.1'); - assert(!(as_u256(2_u128, 2_u128) < as_u256(2_u128, 2_u128)), '2.2<2.2'); - assert(as_u256(1_u128, 2_u128) <= as_u256(2_u128, 2_u128), '1.2<=2.2'); - assert(as_u256(2_u128, 1_u128) <= as_u256(2_u128, 2_u128), '2.1<=2.2'); - assert(!(as_u256(2_u128, 2_u128) <= as_u256(1_u128, 2_u128)), '2.2<=1.2'); - assert(!(as_u256(2_u128, 2_u128) <= as_u256(2_u128, 1_u128)), '2.2<=2.1'); - assert(as_u256(2_u128, 2_u128) <= as_u256(2_u128, 2_u128), '2.2<=2.2'); - assert(!(as_u256(1_u128, 2_u128) > as_u256(2_u128, 2_u128)), '1.2>2.2'); - assert(!(as_u256(2_u128, 1_u128) > as_u256(2_u128, 2_u128)), '2.1>2.2'); - assert(as_u256(2_u128, 2_u128) > as_u256(1_u128, 2_u128), '2.2>1.2'); - assert(as_u256(2_u128, 2_u128) > as_u256(2_u128, 1_u128), '2.2>2.1'); - assert(!(as_u256(2_u128, 2_u128) > as_u256(2_u128, 2_u128)), '2.2>2.2'); - assert(!(as_u256(1_u128, 2_u128) >= as_u256(2_u128, 2_u128)), '1.2>=2.2'); - assert(!(as_u256(2_u128, 1_u128) >= as_u256(2_u128, 2_u128)), '2.1>=2.2'); - assert(as_u256(2_u128, 2_u128) >= as_u256(1_u128, 2_u128), '2.2>=1.2'); - assert(as_u256(2_u128, 2_u128) >= as_u256(2_u128, 1_u128), '2.2>=2.1'); - assert(as_u256(2_u128, 2_u128) >= as_u256(2_u128, 2_u128), '2.2>=2.2'); -} - -#[test] -#[should_panic] -fn test_u256_add_overflow() { - as_u256(pow_2_127(), 1_u128) + as_u256(pow_2_127(), 1_u128); -} - -#[test] -#[should_panic] -fn test_u256_sub_overflow() { - as_u256(1_u128, 1_u128) - as_u256(1_u128, 2_u128); -} - -#[test] -#[should_panic] -fn test_u256_mul_overflow_1() { - as_u256(1_u128, 1_u128) * as_u256(1_u128, 2_u128); -} - -#[test] -#[should_panic] -fn test_u256_mul_overflow_2() { - as_u256(0_u128, pow_2_127()) * as_u256(2_u128, 0_u128); -} - -fn test_array_helper() -> Array:: { - let mut arr = ArrayTrait::new(); - arr.append(10); - arr.append(11); - arr.append(12); - arr -} - -#[test] -fn test_array() { - let arr = test_array_helper(); - assert(*arr.at(0_usize) == 10, 'array[0] == 10'); - assert(*arr.at(1_usize) == 11, 'array[1] == 11'); - assert(*arr.at(2_usize) == 12, 'array[2] == 12'); -} - -#[test] -#[should_panic] -fn test_array_out_of_bound_1() { - let arr = test_array_helper(); - arr.at(3_usize); -} - -#[test] -#[should_panic] -fn test_array_out_of_bound_2() { - let arr = test_array_helper(); - arr.at(11_usize); -} - -#[test] -fn test_felt252_clone() { - let felt252_snap = @2; - let felt252_clone = felt252_snap.clone(); - assert(felt252_clone == 2, 'felt252_clone == 2'); -} - -use clone::Clone; -use array::ArrayTCloneImpl; -#[test] -#[available_gas(100000)] -fn test_array_clone() { - let felt252_snap_array = @test_array_helper(); - let felt252_snap_array_clone = felt252_snap_array.clone(); - assert(felt252_snap_array_clone.len() == 3_usize, 'array len == 3'); - assert(*felt252_snap_array_clone.at(0_usize) == 10, 'array[0] == 10'); - assert(*felt252_snap_array_clone.at(1_usize) == 11, 'array[1] == 11'); - assert(*felt252_snap_array_clone.at(2_usize) == 12, 'array[2] == 12'); -} - -#[test] -fn test_dict_new() -> Felt252Dict:: { - Felt252DictTrait::new() -} - -#[test] -fn test_dict_squash_empty() { - let mut dict: Felt252Dict:: = Felt252DictTrait::new(); - let squashed_dict = dict.squash(); -} - -#[test] -fn test_dict_default_val() { - let mut dict = Felt252DictTrait::new(); - let default_val = dict.get(0); - let squashed_dict = dict.squash(); - assert(default_val == 0, 'default_val == 0'); -} - -// TODO(Gil): Assert before the squash when drop will autosquash the dict. -#[test] -fn test_dict_write_read() { - let mut dict = Felt252DictTrait::new(); - dict.insert(10, 110); - dict.insert(11, 111); - let val10 = dict.get(10); - let val11 = dict.get(11); - let val12 = dict.get(12); - let squashed_dict = dict.squash(); - assert(val10 == 110, 'dict[10] == 110'); - assert(val11 == 111, 'dict[11] == 111'); - assert(val12 == 0, 'default_val == 0'); -} - -#[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(boxed_x.unbox() == 10, 'x == 10'); - assert(boxed_y.unbox() == 11, 'y == 11'); -} - - -// Test objects of size>1. -#[test] -fn test_box_unbox_u256() { - let x = as_u256(1_u128, 0_u128); - let boxed_x = BoxTrait::new(x); - let y = as_u256(1_u128, 1_u128); - let boxed_y = BoxTrait::new(y); - assert(boxed_x.unbox() == as_u256(1_u128, 0_u128), 'unbox u256 x'); - assert(boxed_y.unbox() == as_u256(1_u128, 1_u128), 'unbox u256 y'); -} - -#[test] -fn test_span() { - let mut span = test_array_helper().span(); - - assert(span.len() == 3_u32, 'Unexpected span length.'); - assert(*span.get(0_u32).unwrap().unbox() == 10, 'Unexpected element'); - assert(*span.pop_front().unwrap() == 10, 'Unexpected element'); - assert(span.len() == 2_u32, 'Unexpected span length.'); - assert(*span.at(1_u32) == 12, 'Unexpected element'); -} - -#[test] -fn test_get_available_gas_no_gas_supply() { - assert(testing::get_available_gas() == 0_u128, 'expected no_gas_supply') -} - -#[test] -#[available_gas(10000)] -fn test_get_available_gas_with_gas_supply() { - assert(testing::get_available_gas() > 5000_u128, 'high amount of gas used') -} +mod array_test; +mod bool_test; +mod box_test; +mod dict_test; +mod ec_test; +mod felt_test; +mod hash_test; +mod integer_test; +mod plugins_test; +mod testing_test; diff --git a/corelib/src/test/array_test.cairo b/corelib/src/test/array_test.cairo new file mode 100644 index 000000000..cc6b6ba9b --- /dev/null +++ b/corelib/src/test/array_test.cairo @@ -0,0 +1,88 @@ +use array::ArrayTrait; +use array::SpanTrait; +use box::BoxTrait; +use clone::Clone; +use option::OptionTrait; + +fn test_array_helper() -> Array { + let mut arr = ArrayTrait::new(); + arr.append(10); + arr.append(11); + arr.append(12); + arr +} + +#[test] +fn test_array() { + let arr = test_array_helper(); + assert(*arr[0] == 10, 'array[0] == 10'); + assert(*arr[1] == 11, 'array[1] == 11'); + assert(*arr[2] == 12, 'array[2] == 12'); +} + +#[test] +#[should_panic] +fn test_array_out_of_bound_1() { + let arr = test_array_helper(); + arr[3]; +} + +#[test] +#[should_panic] +fn test_array_out_of_bound_2() { + let arr = test_array_helper(); + arr[11]; +} + +#[test] +#[available_gas(100000)] +fn test_array_clone() { + let felt252_snap_array = @test_array_helper(); + let felt252_snap_array_clone = felt252_snap_array.clone(); + assert(felt252_snap_array_clone.len() == 3, 'array len == 3'); + assert(*felt252_snap_array_clone[0] == 10, 'array[0] == 10'); + assert(*felt252_snap_array_clone[1] == 11, 'array[1] == 11'); + assert(*felt252_snap_array_clone[2] == 12, 'array[2] == 12'); +} + +#[test] +fn test_span() { + let mut span = test_array_helper().span(); + + assert(span.len() == 3, 'Unexpected span length.'); + assert(*span.get(0).unwrap().unbox() == 10, 'Unexpected element'); + assert(*span.pop_front().unwrap() == 10, 'Unexpected element'); + assert(span.len() == 2, 'Unexpected span length.'); + assert(*span[1] == 12, 'Unexpected element'); + assert(*span.pop_back().unwrap() == 12, 'Unexpected element'); + assert(span.len() == 1, 'Unexpected span length.'); +} + +#[test] +fn test_slice() { + let mut span = test_array_helper().span(); + assert(span.slice(0, 3).len() == 3, 'Unexpected span length.'); + assert(*span.slice(0, 3)[0] == 10, 'Unexpected Element.'); + assert(span.slice(0, 2).len() == 2, 'Unexpected span length.'); + assert(*span.slice(0, 2)[0] == 10, 'Unexpected Element.'); + assert(span.slice(0, 1).len() == 1, 'Unexpected span length.'); + assert(*span.slice(0, 1)[0] == 10, 'Unexpected Element.'); + assert(span.slice(0, 0).len() == 0, 'Unexpected span length.'); + assert(span.slice(1, 2).len() == 2, 'Unexpected span length.'); + assert(*span.slice(1, 2)[0] == 11, 'Unexpected Element.'); + assert(span.slice(1, 1).len() == 1, 'Unexpected span length.'); + assert(*span.slice(1, 1)[0] == 11, 'Unexpected Element.'); + assert(span.slice(1, 0).len() == 0, 'Unexpected span length.'); +} + +#[test] +#[should_panic] +fn test_slice_out_of_bound_1() { + test_array_helper().span().slice(3, 1); +} + +#[test] +#[should_panic] +fn test_slice_out_of_bound_2() { + test_array_helper().span().slice(0, 4); +} diff --git a/corelib/src/test/bool_test.cairo b/corelib/src/test/bool_test.cairo new file mode 100644 index 000000000..0dcb3d189 --- /dev/null +++ b/corelib/src/test/bool_test.cairo @@ -0,0 +1,21 @@ +#[test] +fn test_bool_operators() { + assert(true == true, 't == t'); + assert(false == false, 'f == f'); + assert(!true == false, '!t == f'); + assert(!false == true, '!f == t'); + assert(true != false, 't != f'); + assert(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)'); +} diff --git a/corelib/src/test/box_test.cairo b/corelib/src/test/box_test.cairo new file mode 100644 index 000000000..266b9b953 --- /dev/null +++ b/corelib/src/test/box_test.cairo @@ -0,0 +1,22 @@ +use box::BoxTrait; + +#[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(boxed_x.unbox() == 10, 'x == 10'); + assert(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(boxed_x.unbox() == x, 'unbox u256 x'); + assert(boxed_y.unbox() == y, 'unbox u256 y'); +} diff --git a/corelib/src/test/dict_test.cairo b/corelib/src/test/dict_test.cairo new file mode 100644 index 000000000..53f7a2616 --- /dev/null +++ b/corelib/src/test/dict_test.cairo @@ -0,0 +1,63 @@ +use dict::Felt252DictTrait; +use traits::Index; + +#[test] +fn test_dict_new() -> Felt252Dict { + Felt252DictTrait::new() +} + +#[test] +fn test_dict_squash_empty() { + let mut dict: Felt252Dict = Felt252DictTrait::new(); + let squashed_dict = dict.squash(); +} + +#[test] +fn test_dict_default_val() { + let mut dict = Felt252DictTrait::new(); + let default_val = dict.get(0); + assert(default_val == 0, 'default_val == 0'); +} + +#[test] +fn test_dict_write_read() { + let mut dict = Felt252DictTrait::new(); + dict.insert(10, 110); + dict.insert(11, 111); + // TODO(spapini): Use indexing operator. + let val10 = dict.index(10); + let val11 = dict.index(11); + let val12 = dict.index(12); + assert(val10 == 110, 'dict[10] == 110'); + assert(val11 == 111, 'dict[11] == 111'); + assert(val12 == 0, 'default_val == 0'); +} + +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 = Felt252DictTrait::new(); + + dict.insert(KEY1, 1); + dict.insert(KEY2, 2); + dict.insert(KEY3, 3); + dict.insert(KEY4, 4); + dict.insert(KEY5, 5); + + // TODO(spapini): Use indexing operator. + assert(dict.index(KEY1) == 1, 'KEY1'); + assert(dict.index(KEY2) == 2, 'KEY2'); + assert(dict.index(KEY3) == 3, 'KEY3'); + assert(dict.index(KEY4) == 4, 'KEY4'); + assert(dict.index(KEY5) == 5, 'KEY5'); +} diff --git a/corelib/src/test/ec_test.cairo b/corelib/src/test/ec_test.cairo new file mode 100644 index 000000000..b1f506ea8 --- /dev/null +++ b/corelib/src/test/ec_test.cairo @@ -0,0 +1,137 @@ +use core::traits::Into; +use option::OptionTrait; +use ec::ec_mul; +use ec::ec_neg; +use ec::ec_point_from_x; +use ec::ec_point_from_x_nz; +use ec::ec_point_is_zero; +use ec::ec_point_new; +use ec::ec_point_new_nz; +use ec::ec_point_non_zero; +use ec::ec_point_try_new; +use ec::ec_point_try_new_nz; +use ec::ec_point_unwrap; +use ec::ec_point_zero; +use ec::ec_state_add_mul; +use ec::ec_state_add; +use ec::ec_state_finalize; +use ec::ec_state_init; +use ec::ec_state_try_finalize_nz; + +#[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 = ec_point_from_x(1).unwrap(); + let p_nz = ec_point_non_zero(p); + let (x, y) = ec_point_unwrap(p_nz); + assert(x == 1, 'x != 1'); + assert(y == beta_p2_root | y == -beta_p2_root, 'y is wrong'); + + let mut state = ec_state_init(); + ec_state_add(ref state, p_nz); + let q = ec_state_try_finalize_nz(state).expect('zero point'); + let (qx, qy) = ec_point_unwrap(q); + assert(qx == x, 'bad finalize x'); + assert(qy == y, 'bad finalize y'); + + // Try doing the same thing with the EC op builtin. + let mut state = ec_state_init(); + ec_state_add_mul(ref state, 1, p_nz); + let q3 = ec_state_try_finalize_nz(state).expect('zero point'); + let (qx, qy) = ec_point_unwrap(q3); + assert(qx == x, 'bad EC op x'); + assert(qy == y, 'bad EC op y'); + + // Try computing `p + p` using the ec_mul function. + let double_p = ec_mul(p, 2); + let (double_x, double_y) = ec_point_unwrap(ec_point_non_zero(double_p)); + let expected_double_y = + 3572434102142093425782752266058856056057826477682467661647843687948039943621; + assert( + 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) = ec_point_unwrap(ec_point_non_zero(double_p - p)); + assert(sub_x == x, 'bad x for 2p - p'); + assert(sub_y == y, 'bad y for 2p - p'); + + // Compute `p - p`. + assert(ec_point_is_zero(p - p).into(), 'p - p did not return 0.'); + + // Compute `(-p) - p`. + let (sub2_x, sub2_y) = ec_point_unwrap(ec_point_non_zero(ec_neg(p) - p)); + assert(sub2_x == double_x, 'bad x for (-p) - p'); + assert(sub2_y == -double_y, 'bad y for (-p) - p'); +} + +#[test] +#[should_panic] +fn test_bad_ec_point_creation() { + ec_point_new(0, 0); +} + +#[test] +fn test_ec_point_finalization_zero() { + let state = ec_state_init(); + let point_at_infinity = ec_state_try_finalize_nz(state); + 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_ec_mul() { + let p = ec_point_new( + x: 336742005567258698661916498343089167447076063081786685068305785816009957563, + y: 1706004133033694959518200210163451614294041810778629639790706933324248611779, + ); + let m = 2713877091499598330239944961141122840311015265600950719674787125185463975936; + let (x, y) = ec_point_unwrap(ec_point_non_zero(ec_mul(p, m))); + + assert( + x == 2881632108168892236043523177391659237686965655035240771134509747985978822780, + 'ec_mul failed (x).' + ); + assert( + y == 591135563672138037839394207500885413019058613584891498394077262936524140839, + 'ec_mul failed (y).' + ); +} diff --git a/corelib/src/test/felt_test.cairo b/corelib/src/test/felt_test.cairo new file mode 100644 index 000000000..d466179c7 --- /dev/null +++ b/corelib/src/test/felt_test.cairo @@ -0,0 +1,19 @@ +use clone::Clone; + +#[test] +fn test_felt252_operators() { + assert(1 + 3 == 4, '1 + 3 == 4'); + assert(3 + 6 == 9, '3 + 6 == 9'); + assert(3 - 1 == 2, '3 - 1 == 2'); + assert(1231 - 231 == 1000, '1231-231=1000'); + assert(1 * 3 == 3, '1 * 3 == 3'); + assert(3 * 6 == 18, '3 * 6 == 18'); + assert(-3 == 1 - 4, '-3 == 1 - 4'); +} + +#[test] +fn test_felt252_clone() { + let felt252_snap = @2; + let felt252_clone = felt252_snap.clone(); + assert(felt252_clone == 2, 'felt252_clone == 2'); +} diff --git a/corelib/src/test/hash_test.cairo b/corelib/src/test/hash_test.cairo new file mode 100644 index 000000000..6c6ae2ad7 --- /dev/null +++ b/corelib/src/test/hash_test.cairo @@ -0,0 +1,54 @@ +use array::ArrayTrait; + +#[test] +fn test_pedersen_hash() { + assert( + hash::pedersen( + 1, 2 + ) == 2592987851775965742543459319508348457290966253241455514226127639100457844774, + 'Wrong hash value' + ); +} + +#[test] +fn test_poseidon_hades_permutation() { + let (s0, s1, s2) = poseidon::hades_permutation(1, 2, 3); + assert( + s0 == 442682200349489646213731521593476982257703159825582578145778919623645026501, + 'wrong s0' + ); + assert( + s1 == 2233832504250924383748553933071188903279928981104663696710686541536735838182, + 'wrong s1' + ); + assert( + s2 == 2512222140811166287287541003826449032093371832913959128171347018667852712082, + 'wrong s2' + ); +} + +#[test] +#[available_gas(300000)] +fn test_poseidon_hash_span() { + let mut input = ArrayTrait::new(); + input.append(1); + input.append(2); + input.append(3); + + // Test odd number of inputs. + assert( + poseidon::poseidon_hash_span( + input.span() + ) == 0x2f0d8840bcf3bc629598d8a6cc80cb7c0d9e52d93dab244bbf9cd0dca0ad082, + 'wrong result' + ); + + // Test even number of inputs. + input.append(4); + assert( + poseidon::poseidon_hash_span( + input.span() + ) == 0x26e3ad8b876e02bc8a4fc43dad40a8f81a6384083cabffa190bcf40d512ae1d, + 'wrong result' + ); +} diff --git a/corelib/src/test/integer_test.cairo b/corelib/src/test/integer_test.cairo new file mode 100644 index 000000000..ee23fbd38 --- /dev/null +++ b/corelib/src/test/integer_test.cairo @@ -0,0 +1,661 @@ +use core::traits::Into; +use core::traits::Default; +use integer::BoundedInt; + +#[test] +fn test_u8_operators() { + assert(1_u8 == 1_u8, '1 == 1'); + assert(1_u8 != 2_u8, '1 != 2'); + assert(1_u8 + 3_u8 == 4_u8, '1 + 3 == 4'); + assert(3_u8 + 6_u8 == 9_u8, '3 + 6 == 9'); + assert(3_u8 - 1_u8 == 2_u8, '3 - 1 == 2'); + assert(1_u8 * 3_u8 == 3_u8, '1 * 3 == 3'); + assert(2_u8 * 4_u8 == 8_u8, '2 * 4 == 8'); + assert(19_u8 / 7_u8 == 2_u8, '19 / 7 == 2'); + assert(19_u8 % 7_u8 == 5_u8, '19 % 7 == 5'); + assert(231_u8 - 131_u8 == 100_u8, '231-131=100'); + assert(1_u8 < 4_u8, '1 < 4'); + assert(1_u8 <= 4_u8, '1 <= 4'); + assert(!(4_u8 < 4_u8), '!(4 < 4)'); + assert(4_u8 <= 4_u8, '4 <= 4'); + assert(5_u8 > 2_u8, '5 > 2'); + assert(5_u8 >= 2_u8, '5 >= 2'); + assert(!(3_u8 > 3_u8), '!(3 > 3)'); + assert(3_u8 >= 3_u8, '3 >= 3'); +} + +#[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] +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(1_u16 == 1_u16, '1 == 1'); + assert(1_u16 != 2_u16, '1 != 2'); + assert(1_u16 + 3_u16 == 4_u16, '1 + 3 == 4'); + assert(3_u16 + 6_u16 == 9_u16, '3 + 6 == 9'); + assert(3_u16 - 1_u16 == 2_u16, '3 - 1 == 2'); + assert(231_u16 - 131_u16 == 100_u16, '231-131=100'); + assert(1_u16 * 3_u16 == 3_u16, '1 * 3 == 3'); + assert(2_u16 * 4_u16 == 8_u16, '2 * 4 == 8'); + assert(51725_u16 / 7_u16 == 7389_u16, '51725 / 7 == 7389'); + assert(51725_u16 % 7_u16 == 2_u16, '51725 % 7 == 2'); + assert(1_u16 < 4_u16, '1 < 4'); + assert(1_u16 <= 4_u16, '1 <= 4'); + assert(!(4_u16 < 4_u16), '!(4 < 4)'); + assert(4_u16 <= 4_u16, '4 <= 4'); + assert(5_u16 > 2_u16, '5 > 2'); + assert(5_u16 >= 2_u16, '5 >= 2'); + assert(!(3_u16 > 3_u16), '!(3 > 3)'); + assert(3_u16 >= 3_u16, '3 >= 3'); +} + +#[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] +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(1_u32 == 1_u32, '1 == 1'); + assert(1_u32 != 2_u32, '1 != 2'); + assert(1_u32 + 3_u32 == 4_u32, '1 + 3 == 4'); + assert(3_u32 + 6_u32 == 9_u32, '3 + 6 == 9'); + assert(3_u32 - 1_u32 == 2_u32, '3 - 1 == 2'); + assert(231_u32 - 131_u32 == 100_u32, '231-131=100'); + assert(1_u32 * 3_u32 == 3_u32, '1 * 3 == 3'); + assert(2_u32 * 4_u32 == 8_u32, '2 * 4 == 8'); + assert(510670725_u32 / 7_u32 == 72952960_u32, '510670725 / 7 == 72952960'); + assert(510670725_u32 % 7_u32 == 5_u32, '510670725 % 7 == 5'); + assert(1_u32 < 4_u32, '1 < 4'); + assert(1_u32 <= 4_u32, '1 <= 4'); + assert(!(4_u32 < 4_u32), '!(4 < 4)'); + assert(4_u32 <= 4_u32, '4 <= 4'); + assert(5_u32 > 2_u32, '5 > 2'); + assert(5_u32 >= 2_u32, '5 >= 2'); + assert(!(3_u32 > 3_u32), '!(3 > 3)'); + assert(3_u32 >= 3_u32, '3 >= 3'); +} + +#[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] +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(1_u64 == 1_u64, '1 == 1'); + assert(1_u64 != 2_u64, '1 != 2'); + assert(1_u64 + 3_u64 == 4_u64, '1 + 3 == 4'); + assert(3_u64 + 6_u64 == 9_u64, '3 + 6 == 9'); + assert(3_u64 - 1_u64 == 2_u64, '3 - 1 == 2'); + assert(231_u64 - 131_u64 == 100_u64, '231-131=100'); + assert(1_u64 * 3_u64 == 3_u64, '1 * 3 == 3'); + assert(2_u64 * 4_u64 == 8_u64, '2 * 4 == 8'); + assert(5010670477878974275_u64 / 7_u64 == 715810068268424896_u64, 'Wrong division result.'); + assert(5010670477878974275_u64 % 7_u64 == 3_u64, '5010670477878974275 % 7 == 3'); + assert(1_u64 < 4_u64, '1 < 4'); + assert(1_u64 <= 4_u64, '1 <= 4'); + assert(!(4_u64 < 4_u64), '!(4 < 4)'); + assert(4_u64 <= 4_u64, '4 <= 4'); + assert(5_u64 > 2_u64, '5 > 2'); + assert(5_u64 >= 2_u64, '5 >= 2'); + assert(!(3_u64 > 3_u64), '!(3 > 3)'); + assert(3_u64 >= 3_u64, '3 >= 3'); +} + +#[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] +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(1_u128 == 1_u128, '1 == 1'); + assert(!(1_u128 == 2_u128), '!(1 == 2)'); + assert(1_u128 + 3_u128 == 4_u128, '1 + 3 == 4'); + assert(3_u128 + 6_u128 == 9_u128, '3 + 6 == 9'); + assert(3_u128 - 1_u128 == 2_u128, '3 - 1 == 2'); + assert(1231_u128 - 231_u128 == 1000_u128, '1231-231=1000'); + assert(1_u128 * 3_u128 == 3_u128, '1 * 3 == 3'); + assert(2_u128 * 4_u128 == 8_u128, '2 * 4 == 8'); + assert(8_u128 / 2_u128 == 4_u128, '8 / 2 == 4'); + assert(8_u128 % 2_u128 == 0_u128, '8 % 2 == 0'); + assert(7_u128 / 3_u128 == 2_u128, '7 / 3 == 2'); + assert(7_u128 % 3_u128 == 1_u128, '7 % 3 == 1'); + assert(1_u128 < 4_u128, '1 < 4'); + assert(1_u128 <= 4_u128, '1 <= 4'); + assert(!(4_u128 < 4_u128), '!(4 < 4)'); + assert(4_u128 <= 4_u128, '4 <= 4'); + assert(5_u128 > 2_u128, '5 > 2'); + assert(5_u128 >= 2_u128, '5 >= 2'); + assert(!(3_u128 > 3_u128), '!(3 > 3)'); + assert(3_u128 >= 3_u128, '3 >= 3'); + assert((1_u128 | 2_u128) == 3_u128, '1 | 2 == 3'); + assert((1_u128 & 2_u128) == 0_u128, '1 & 2 == 0'); + assert((1_u128 ^ 2_u128) == 3_u128, '1 ^ 2 == 3'); + assert((2_u128 | 2_u128) == 2_u128, '2 | 2 == 2'); + assert((2_u128 & 2_u128) == 2_u128, '2 & 2 == 2'); + assert((2_u128 & 3_u128) == 2_u128, '2 & 3 == 2'); + assert((3_u128 ^ 6_u128) == 5_u128, '3 ^ 6 == 5'); + assert(u128_sqrt(9_u128) == 3_u128, 'u128_sqrt(9) == 3'); + assert(u128_sqrt(10_u128) == 3_u128, 'u128_sqrt(10) == 3'); + assert( + u128_sqrt(1267650600228229401496703205376_u128) == 1125899906842624_u128, + 'u128_sqrt(2^100) == 2^50' + ); + assert( + u128_sqrt(340282366920938463463374607431768211455_u128) == 18446744073709551615_u128, + 'Wrong square root result.' + ); + assert(u128_sqrt(1_u128) == 1_u128, 'u128_sqrt(1) == 1'); + assert(u128_sqrt(0_u128) == 0_u128, 'u128_sqrt(0) == 0'); +} + +fn pow_2_127() -> u128 { + 0x80000000000000000000000000000000_u128 +} + +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] +#[should_panic] +fn test_u128_add_overflow_1() { + pow_2_127() + pow_2_127(); +} + +#[test] +#[should_panic] +fn test_u128_add_overflow_2() { + (pow_2_127() + 12_u128) + pow_2_127(); +} + +#[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 * pow_2_127(); +} + +#[test] +#[should_panic] +fn test_u128_div_by_0() { + 2_u128 / 0_u128; +} + +#[test] +#[should_panic] +fn test_u128_mod_by_0() { + 2_u128 % 0_u128; +} + +// TODO(orizi): Remove when u256 literals are supported. +fn as_u256(high: u128, low: u128) -> u256 { + u256 { low, high } +} + +#[test] +fn test_u256_from_felt252() { + assert(1.into() == as_u256(0_u128, 1_u128), 'into 1'); + assert( + (170141183460469231731687303715884105728 * 2).into() == as_u256(1_u128, 0_u128), + 'into 2**128' + ); +} + +// TODO(orizi): Use u256 literals when supported. +#[test] +fn test_u256_operators() { + let max_u128 = 0xffffffffffffffffffffffffffffffff; + assert(as_u256(1, 1) + as_u256(3, 2) == as_u256(4, 3), 'no Overflow'); + assert(as_u256(1, pow_2_127()) + as_u256(3, pow_2_127()) == as_u256(5, 0), 'basic Overflow'); + assert(as_u256(4, 3) - as_u256(1, 1) == as_u256(3, 2), 'no UF'); + assert(as_u256(5, 0) - as_u256(1, pow_2_127()) == as_u256(3, pow_2_127()), 'basic UF'); + assert(as_u256(4, 3) * as_u256(0, 1) == as_u256(4, 3), 'mul by 1'); + assert(as_u256(4, 3) * as_u256(0, 2) == as_u256(8, 6), 'mul by 2'); + assert(as_u256(0, pow_2_127()) * as_u256(0, 2) == as_u256(1, 0), 'basic mul Overflow'); + assert( + as_u256(0, max_u128) + * as_u256(0, max_u128) == as_u256(0xfffffffffffffffffffffffffffffffe, 1), + 'max_u128 * max_u128' + ); + assert(as_u256(0, max_u128) * as_u256(0, 1) == as_u256(0, max_u128), 'max_u128 * 1'); + assert(as_u256(0, 1) * as_u256(0, max_u128) == as_u256(0, max_u128), '1 * max_u128'); + assert((as_u256(1, 2) | as_u256(2, 2)) == as_u256(3, 2), '1.2|2.2==3.2'); + assert((as_u256(2, 1) | as_u256(2, 2)) == as_u256(2, 3), '2.1|2.2==2.3'); + assert((as_u256(2, 2) | as_u256(1, 2)) == as_u256(3, 2), '2.2|1.2==3.2'); + assert((as_u256(2, 2) | as_u256(2, 1)) == as_u256(2, 3), '2.2|2.1==2.3'); + assert((as_u256(1, 2) & as_u256(2, 2)) == as_u256(0, 2), '1.2&2.2==0.2'); + assert((as_u256(2, 1) & as_u256(2, 2)) == as_u256(2, 0), '2.1&2.2==2.0'); + assert((as_u256(2, 2) & as_u256(1, 2)) == as_u256(0, 2), '2.2&1.2==0.2'); + assert((as_u256(2, 2) & as_u256(2, 1)) == as_u256(2, 0), '2.2&2.1==2.0'); + assert((as_u256(1, 2) ^ as_u256(2, 2)) == as_u256(3, 0), '1.2^2.2==3.0'); + assert((as_u256(2, 1) ^ as_u256(2, 2)) == as_u256(0, 3), '2.1^2.2==0.3'); + assert((as_u256(2, 2) ^ as_u256(1, 2)) == as_u256(3, 0), '2.2^1.2==3.0'); + assert((as_u256(2, 2) ^ as_u256(2, 1)) == as_u256(0, 3), '2.2^2.1==0.3'); + assert(as_u256(1, 2) < as_u256(2, 2), '1.2<2.2'); + assert(as_u256(2, 1) < as_u256(2, 2), '2.1<2.2'); + assert(!(as_u256(2, 2) < as_u256(1, 2)), '2.2<1.2'); + assert(!(as_u256(2, 2) < as_u256(2, 1)), '2.2<2.1'); + assert(!(as_u256(2, 2) < as_u256(2, 2)), '2.2<2.2'); + assert(as_u256(1, 2) <= as_u256(2, 2), '1.2<=2.2'); + assert(as_u256(2, 1) <= as_u256(2, 2), '2.1<=2.2'); + assert(!(as_u256(2, 2) <= as_u256(1, 2)), '2.2<=1.2'); + assert(!(as_u256(2, 2) <= as_u256(2, 1)), '2.2<=2.1'); + assert(as_u256(2, 2) <= as_u256(2, 2), '2.2<=2.2'); + assert(!(as_u256(1, 2) > as_u256(2, 2)), '1.2>2.2'); + assert(!(as_u256(2, 1) > as_u256(2, 2)), '2.1>2.2'); + assert(as_u256(2, 2) > as_u256(1, 2), '2.2>1.2'); + assert(as_u256(2, 2) > as_u256(2, 1), '2.2>2.1'); + assert(!(as_u256(2, 2) > as_u256(2, 2)), '2.2>2.2'); + assert(!(as_u256(1, 2) >= as_u256(2, 2)), '1.2>=2.2'); + assert(!(as_u256(2, 1) >= as_u256(2, 2)), '2.1>=2.2'); + assert(as_u256(2, 2) >= as_u256(1, 2), '2.2>=1.2'); + assert(as_u256(2, 2) >= as_u256(2, 1), '2.2>=2.1'); + assert(as_u256(2, 2) >= as_u256(2, 2), '2.2>=2.2'); + + assert(as_u256(3, 2) / as_u256(1, 1) == as_u256(0, 2), 'u256 div'); + assert( + as_u256(4, 2) / as_u256(0, 3) == as_u256(1, 113427455640312821154458202477256070486), + 'u256 div' + ); + assert( + as_u256(0, 18446744073709551616) / as_u256(0, 18446744073709551616) == as_u256(0, 1), + 'u256 div' + ); +} + +#[test] +#[should_panic] +fn test_u256_add_overflow() { + as_u256(pow_2_127(), 1_u128) + as_u256(pow_2_127(), 1_u128); +} + +#[test] +#[should_panic] +fn test_u256_sub_overflow() { + as_u256(1_u128, 1_u128) - as_u256(1_u128, 2_u128); +} + +#[test] +#[should_panic] +fn test_u256_mul_overflow_1() { + as_u256(1_u128, 1_u128) * as_u256(1_u128, 2_u128); +} + +#[test] +#[should_panic] +fn test_u256_mul_overflow_2() { + as_u256(0_u128, pow_2_127()) * as_u256(2_u128, 0_u128); +} + +#[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(min_u8 == 0_u8, 'not zero'); + assert(min_u16 == 0_u16, 'not zero'); + assert(min_u32 == 0_u32, 'not zero'); + assert(min_u64 == 0_u64, 'not zero'); + assert(min_u128 == 0_u128, 'not zero'); + assert(min_u256 == as_u256(0_u128, 0_u128), '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(max_u8 == 0xff_u8, 'not max'); + assert(max_u16 == 0xffff_u16, 'not max'); + assert(max_u32 == 0xffffffff_u32, 'not max'); + assert(max_u64 == 0xffffffffffffffff_u64, 'not max'); + assert(max_u128 == 0xffffffffffffffffffffffffffffffff_u128, 'not max'); + assert(max_u256 == as_u256(max_u128, max_u128), '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() + 1.into(); +} + + +#[test] +fn test_default_values() { + assert(Default::default() == 0, '0 == 0'); + assert(Default::default() == 0_u8, '0 == 0'); + assert(Default::default() == 0_u16, '0 == 0'); + assert(Default::default() == 0_u32, '0 == 0'); + assert(Default::default() == 0_u64, '0 == 0'); + assert(Default::default() == 0_u128, '0 == 0'); + assert(Default::default() == u256 { low: 0_u128, high: 0_u128 }, '0 == 0'); +} + +#[test] +fn test_default_felt252dict_values() { + assert(Felt252DictValue::zero_default() == 0, '0 == 0'); + assert(Felt252DictValue::zero_default() == 0_u8, '0 == 0'); + assert(Felt252DictValue::zero_default() == 0_u16, '0 == 0'); + assert(Felt252DictValue::zero_default() == 0_u32, '0 == 0'); + assert(Felt252DictValue::zero_default() == 0_u64, '0 == 0'); + assert(Felt252DictValue::zero_default() == 0_u128, '0 == 0'); +} diff --git a/corelib/src/test/plugins_test.cairo b/corelib/src/test/plugins_test.cairo new file mode 100644 index 000000000..3f8c8e838 --- /dev/null +++ b/corelib/src/test/plugins_test.cairo @@ -0,0 +1,46 @@ +use array::ArrayTrait; +use array::SpanTrait; +use serde::Serde; +use option::OptionTrait; + +#[derive(Copy, Drop, Serde, PartialEq)] +enum EnumForSerde { + A: (), + B: u32, + C: u64, +} + +#[test] +fn test_derive_serde_enum() { + let a = EnumForSerde::A(()); + let b = EnumForSerde::B(1); + let c = EnumForSerde::C(2); + let mut output = ArrayTrait::new(); + Serde::serialize(ref output, a); + Serde::serialize(ref output, a); + Serde::serialize(ref output, c); + Serde::serialize(ref output, b); + Serde::serialize(ref output, a); + let mut serialized = output.span(); + assert( + Serde::::deserialize(ref serialized).expect('failed to read') == a, + 'expected a' + ); + assert( + Serde::::deserialize(ref serialized).expect('failed to read') == a, + 'expected a' + ); + assert( + Serde::::deserialize(ref serialized).expect('failed to read') == c, + 'expected c' + ); + assert( + Serde::::deserialize(ref serialized).expect('failed to read') == b, + 'expected b' + ); + assert( + Serde::::deserialize(ref serialized).expect('failed to read') == a, + 'expected a' + ); + assert(serialized.is_empty(), 'expected empty'); +} diff --git a/corelib/src/test/testing_test.cairo b/corelib/src/test/testing_test.cairo new file mode 100644 index 000000000..117331bf1 --- /dev/null +++ b/corelib/src/test/testing_test.cairo @@ -0,0 +1,28 @@ +#[test] +#[should_panic(expected: ('panic_with_felt252()', ))] +fn test_panic_with_felt252() { + // No semicolon here: Missing implementation for core::traits::Drop:: + 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] +fn test_get_available_gas_no_gas_supply() { + assert(testing::get_available_gas() == 0, 'expected no_gas_supply') +} + +#[test] +#[available_gas(10000)] +fn test_get_available_gas_with_gas_supply() { + assert(testing::get_available_gas() > 5000, 'high amount of gas used') +} diff --git a/corelib/src/traits.cairo b/corelib/src/traits.cairo index 1093eb72f..ca98a0b1d 100644 --- a/corelib/src/traits.cairo +++ b/corelib/src/traits.cairo @@ -1,9 +1,12 @@ trait Copy; trait Drop; +impl SnapshotCopy of Copy<@T>; +impl SnapshotDrop of Drop<@T>; + // TODO(spapini): When associated types are supported, support the general trait Add. trait Add { - fn add(a: T, b: T) -> T; + fn add(lhs: T, rhs: T) -> T; } trait AddEq { fn add_eq(ref self: T, other: T); @@ -11,7 +14,7 @@ trait AddEq { // TODO(spapini): When associated types are supported, support the general trait Sub. trait Sub { - fn sub(a: T, b: T) -> T; + fn sub(lhs: T, rhs: T) -> T; } trait SubEq { fn sub_eq(ref self: T, other: T); @@ -19,7 +22,7 @@ trait SubEq { // TODO(spapini): When associated types are supported, support the general trait Mul. trait Mul { - fn mul(a: T, b: T) -> T; + fn mul(lhs: T, rhs: T) -> T; } trait MulEq { fn mul_eq(ref self: T, other: T); @@ -27,7 +30,7 @@ trait MulEq { // TODO(spapini): When associated types are supported, support the general trait Div. trait Div { - fn div(a: T, b: T) -> T; + fn div(lhs: T, rhs: T) -> T; } trait DivEq { fn div_eq(ref self: T, other: T); @@ -35,45 +38,45 @@ trait DivEq { // TODO(spapini): When associated types are supported, support the general trait Rem. trait Rem { - fn rem(a: T, b: T) -> T; + fn rem(lhs: T, rhs: T) -> T; } trait RemEq { fn rem_eq(ref self: T, other: T); } trait PartialEq { - fn eq(a: T, b: T) -> bool; - fn ne(a: T, b: T) -> bool; + fn eq(lhs: T, rhs: T) -> bool; + fn ne(lhs: T, rhs: T) -> bool; } // TODO(spapini): When associated types are supported, support the general trait BitAnd. trait BitAnd { - fn bitand(a: T, b: T) -> T; + fn bitand(lhs: T, rhs: T) -> T; } // TODO(spapini): When associated types are supported, support the general trait BitOr. trait BitOr { - fn bitor(a: T, b: T) -> T; + fn bitor(lhs: T, rhs: T) -> T; } // TODO(spapini): When associated types are supported, support the general trait BitXor. trait BitXor { - fn bitxor(a: T, b: T) -> T; + fn bitxor(lhs: T, rhs: T) -> T; } trait PartialOrd { - fn le(a: T, b: T) -> bool; - fn ge(a: T, b: T) -> bool; - fn lt(a: T, b: T) -> bool; - fn gt(a: T, b: T) -> bool; + 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 convertion between types. +/// Trait for conversion between types. trait Into { fn into(self: T) -> S; } -/// Trait for fallible convertion between types. +/// Trait for fallible conversion between types. trait TryInto { fn try_into(self: T) -> Option; } @@ -85,3 +88,104 @@ trait Neg { 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. +trait IndexView { + fn index(self: @C, index: I) -> V; +} + +trait Index { + fn index(ref self: C, index: I) -> V; +} + +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 {} +} + +trait Default { + fn default() -> T; +} + +/// Trait for default values of value in a dict. Should be logically equivalent to 0. +trait Felt252DictValue { + fn zero_default() -> T nopanic; +} + +// Tuple Copy impls. +impl TupleSize0Copy of Copy<()>; + +impl TupleSize1Copy> of Copy<(E0, )>; + +impl TupleSize2Copy, impl E1Copy: Copy> of Copy<(E0, E1)>; + +impl TupleSize3Copy, +impl E1Copy: Copy, +impl E2Copy: Copy> of Copy<(E0, E1, E2)>; + +impl TupleSize4Copy, +impl E1Copy: Copy, +impl E2Copy: Copy, +impl E3Copy: Copy> of Copy<(E0, E1, E2, E3)>; + +// Tuple Drop impls. +impl TupleSize0Drop of Drop<()>; + +impl TupleSize1Drop> of Drop<(E0, )>; + +impl TupleSize2Drop, impl E1Drop: Drop> of Drop<(E0, E1)>; + +impl TupleSize3Drop, +impl E1Drop: Drop, +impl E2Drop: Drop> of Drop<(E0, E1, E2)>; + +impl TupleSize4Drop, +impl E1Drop: Drop, +impl E2Drop: Drop, +impl E2Drop: 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) + } +} diff --git a/corelib/src/zeroable.cairo b/corelib/src/zeroable.cairo index 82f58a562..9620e4f9a 100644 --- a/corelib/src/zeroable.cairo +++ b/corelib/src/zeroable.cairo @@ -1,3 +1,5 @@ +// === Zeroable === + trait Zeroable { /// Returns the additive identity element of Self, 0. fn zero() -> T; @@ -7,7 +9,7 @@ trait Zeroable { fn is_non_zero(self: T) -> bool; } -impl Felt252Zeroable of Zeroable:: { +impl Felt252Zeroable of Zeroable { fn zero() -> felt252 { 0 } @@ -22,3 +24,29 @@ impl Felt252Zeroable of Zeroable:: { !self.is_zero() } } + +// === NonZero === + +extern type NonZero; +impl NonZeroTCopy> of Copy>; +impl NonZeroTDrop> of Drop>; +enum IsZeroResult { + Zero: (), + NonZero: NonZero, +} +extern fn unwrap_non_zero(a: NonZero) -> T nopanic; + +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, + } + } +} diff --git a/exercises/arrays/README.md b/exercises/arrays/README.md index 5bd735d67..493fa874b 100644 --- a/exercises/arrays/README.md +++ b/exercises/arrays/README.md @@ -7,6 +7,6 @@ This has to do with the fact that once a memory slot is written to, it cannot be ## Further information -- [Arrays](https://medium.com/nethermind-eth/a-first-look-at-cairo-1-0-a-safer-stronger-simpler-provable-programming-language-892ce4c07b38#570c) +- [Arrays](https://cairo-book.github.io/ch02-06-common-collections.html#array) - [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/exercises/arrays/arrays3.cairo b/exercises/arrays/arrays3.cairo index 45f779455..49a560760 100644 --- a/exercises/arrays/arrays3.cairo +++ b/exercises/arrays/arrays3.cairo @@ -24,6 +24,3 @@ fn test_arrays3() { // You should not change the index accessed. a.at(2_usize); } - -// Don't mind this -impl DropFeltSnapshot of Drop::<@felt252>; diff --git a/exercises/enums/README.md b/exercises/enums/README.md index f38fe0216..8f1cab425 100644 --- a/exercises/enums/README.md +++ b/exercises/enums/README.md @@ -6,4 +6,4 @@ Useful in combination with enums is Cairo's "pattern matching" facility, which m ## Further information -- [Enums](https://medium.com/nethermind-eth/a-first-look-at-cairo-1-0-a-safer-stronger-simpler-provable-programming-language-892ce4c07b38#7dff) +- [Enums](https://cairo-book.github.io/ch05-01-enums.html) diff --git a/exercises/enums/enums3.cairo b/exercises/enums/enums3.cairo index bff27868f..7597fa0e6 100644 --- a/exercises/enums/enums3.cairo +++ b/exercises/enums/enums3.cairo @@ -16,7 +16,7 @@ struct Point { y: u8, } -#[derive(Copy)] +#[derive(Drop, Copy)] struct State { color: (u8, u8, u8), position: Point, @@ -74,15 +74,15 @@ fn test_match_message_call() { } -impl TripleTuplePartialEq of PartialEq::<(u8, u8, u8)> { +impl TripleTuplePartialEq of PartialEq<(u8, u8, u8)> { #[inline(always)] - fn eq(a: (u8, u8, u8), b: (u8, u8, u8)) -> bool { - let (a0, a1, a2) = a; - let (b0, b1, b2) = b; + fn eq(lhs: (u8, u8, u8), rhs: (u8, u8, u8)) -> bool { + let (a0, a1, a2) = lhs; + let (b0, b1, b2) = rhs; a0 == b0 & a1 == b1 & a2 == b2 } #[inline(always)] - fn ne(a: (u8, u8, u8), b: (u8, u8, u8)) -> bool { - !(a == b) + fn ne(lhs: (u8, u8, u8), rhs: (u8, u8, u8)) -> bool { + !(lhs == rhs) } } diff --git a/exercises/functions/README.md b/exercises/functions/README.md index 3ac5fcd2f..219414751 100644 --- a/exercises/functions/README.md +++ b/exercises/functions/README.md @@ -1,3 +1,5 @@ # Functions -Here, you'll learn how to write functions. +Here, you'll learn how to write and use functions in Cairo. + +[Functions](https://cairo-book.github.io/ch02-03-functions.html) diff --git a/exercises/if/README.md b/exercises/if/README.md index efc1d87ea..c73230573 100644 --- a/exercises/if/README.md +++ b/exercises/if/README.md @@ -4,4 +4,4 @@ ## Further information -- [Return statements and if expressions](https://medium.com/nethermind-eth/a-first-look-at-cairo-1-0-a-safer-stronger-simpler-provable-programming-language-892ce4c07b38#d97c) +- [If expressions](https://cairo-book.github.io/ch02-05-control-flow.html#if-expressions) diff --git a/exercises/loops/README.md b/exercises/loops/README.md new file mode 100644 index 000000000..9e2de3fa3 --- /dev/null +++ b/exercises/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://cairo-book.github.io/ch02-05-control-flow.html#repetition-with-loops) diff --git a/exercises/loops/loops1.cairo b/exercises/loops/loops1.cairo new file mode 100644 index 000000000..89c26b04a --- /dev/null +++ b/exercises/loops/loops1.cairo @@ -0,0 +1,15 @@ +// loops1.cairo +// Execute `starklings hint loops1` or use the `hint` watch subcommand for a hint. + +// I AM NOT DONE +#[test] +#[available_gas(200000)] +fn test_loop() { + let mut counter = 0; + //TODO make the test pass without changing any existing line + loop { + break (); + counter += 1; + }; + assert(counter == 10, 'counter should be 10') +} diff --git a/exercises/loops/loops2.cairo b/exercises/loops/loops2.cairo new file mode 100644 index 000000000..612ecf706 --- /dev/null +++ b/exercises/loops/loops2.cairo @@ -0,0 +1,18 @@ +// loops2.cairo +// Execute `starklings hint loops2` or use the `hint` watch subcommand for a hint. + +// I AM NOT DONE + +#[test] +#[available_gas(200000)] +fn test_loop() { + let mut counter = 0; + + let result = loop { + if counter == 5 {//TODO return a value from the loop + } + counter += 1; + } + + assert(result == 5, 'result should be 5'); +} diff --git a/exercises/move_semantics/README.md b/exercises/move_semantics/README.md index ad0c66352..00463542c 100644 --- a/exercises/move_semantics/README.md +++ b/exercises/move_semantics/README.md @@ -2,8 +2,7 @@ ## Further information -For this section, reading the Rust book references is especially important. Cairo borrows a lot from rust, including the move semantics. While not everything is the same in Cairo, the concepts are very similar, and while we're waiting for proper Cairo documentation, the Rust book is a great resource. +For this section, reading the Cairo book references is especially important. - -- [Ownership](https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html) -- [Reference and borrowing](https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html) +- [Ownership](https://cairo-book.github.io/ch03-00-understanding-ownership.html) +- [Reference and borrowing](https://cairo-book.github.io/ch03-02-references-and-snapshots.html) diff --git a/exercises/move_semantics/move_semantics1.cairo b/exercises/move_semantics/move_semantics1.cairo index e07afc00c..311298450 100644 --- a/exercises/move_semantics/move_semantics1.cairo +++ b/exercises/move_semantics/move_semantics1.cairo @@ -15,12 +15,12 @@ fn main() { let arr1 = fill_arr(arr0); // This is just a print statement for arrays. - arr1.span().snapshot.clone().print(); + arr1.clone().print(); //TODO fix the error here without modifying this line. arr1.append(88); - arr1.span().snapshot.clone().print(); + arr1.clone().print(); } fn fill_arr(arr: Array) -> Array { diff --git a/exercises/move_semantics/move_semantics3.cairo b/exercises/move_semantics/move_semantics3.cairo index 03fb32825..40aebe690 100644 --- a/exercises/move_semantics/move_semantics3.cairo +++ b/exercises/move_semantics/move_semantics3.cairo @@ -16,11 +16,11 @@ fn main() { let mut arr1 = fill_arr(arr0); - arr1.span().snapshot.clone().print(); + arr1.clone().print(); arr1.append(88); - arr1.span().snapshot.clone().print(); + arr1.clone().print(); } fn fill_arr(arr: Array) -> Array { @@ -29,4 +29,4 @@ fn fill_arr(arr: Array) -> Array { arr.append(66); arr -} \ No newline at end of file +} diff --git a/exercises/move_semantics/move_semantics4.cairo b/exercises/move_semantics/move_semantics4.cairo index defa44912..048a87a65 100644 --- a/exercises/move_semantics/move_semantics4.cairo +++ b/exercises/move_semantics/move_semantics4.cairo @@ -16,11 +16,11 @@ fn main() { let mut arr1 = fill_arr(arr0); - arr1.span().snapshot.clone().print(); + arr1.clone().print(); arr1.append(88); - arr1.span().snapshot.clone().print(); + arr1.clone().print(); } // `fill_arr()` should no longer takes `arr: Array` as argument diff --git a/exercises/operations/README.md b/exercises/operations/README.md index 27dbf5700..1e795888e 100644 --- a/exercises/operations/README.md +++ b/exercises/operations/README.md @@ -1,6 +1,6 @@ # Felt operations -A field element - felt, is a native type in Cairo. Go [here](https://www.cairo-lang.org/docs/how_cairo_works/cairo_intro.html#field-elements) to learn more about it +A field element - felt, is a native type in Cairo. Learn more about it in the [Cairo book](https://cairo-book.github.io/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://github.com/starkware-libs/cairo/blob/34796ef8615a96ea28888421dc2bc498786d01d6/corelib/src/test.cairo#L183) for more details +Take a look [here](https://cairo-book.github.io/ch02-02-data-types.html#integer-types) for more details diff --git a/exercises/options/README.md b/exercises/options/README.md index 980e50f4c..cd5faceaa 100644 --- a/exercises/options/README.md +++ b/exercises/options/README.md @@ -11,4 +11,4 @@ Option types are very common in Cairo code, as they have a number of uses: ## Further Information -- [Option Implementation](https://github.com/starkware-libs/cairo/blob/main/corelib/src/option.cairo) +- [Option Implementation](https://cairo-book.github.io/ch05-01-enums.html#the-option-enum-and-its-advantages) diff --git a/exercises/primitive_types/README.md b/exercises/primitive_types/README.md index 3a9065184..aca972264 100644 --- a/exercises/primitive_types/README.md +++ b/exercises/primitive_types/README.md @@ -2,3 +2,5 @@ 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://cairo-book.github.io/ch02-02-data-types.html) diff --git a/exercises/primitive_types/primitive_types2.cairo b/exercises/primitive_types/primitive_types2.cairo index 18d2b4151..aa0360a0a 100644 --- a/exercises/primitive_types/primitive_types2.cairo +++ b/exercises/primitive_types/primitive_types2.cairo @@ -33,7 +33,7 @@ fn main() { } else if is_numeric( ref your_character ) { - ('Numerical!').print(); + ('Numerical!').print(); } else { ('Neither alphabetic nor numeric!').print(); } @@ -65,21 +65,21 @@ fn is_numeric(ref char: felt252) -> bool { // 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:: { +impl PartialOrdFelt of PartialOrd { #[inline(always)] - fn le(a: felt252, b: felt252) -> bool { - !(b < a) + fn le(lhs: felt252, rhs: felt252) -> bool { + !(rhs < lhs) } #[inline(always)] - fn ge(a: felt252, b: felt252) -> bool { - !(a < b) + fn ge(lhs: felt252, rhs: felt252) -> bool { + !(lhs < rhs) } #[inline(always)] - fn lt(a: felt252, b: felt252) -> bool { - integer::u256_from_felt252(a) < integer::u256_from_felt252(b) + fn lt(lhs: felt252, rhs: felt252) -> bool { + integer::u256_from_felt252(lhs) < integer::u256_from_felt252(rhs) } #[inline(always)] - fn gt(a: felt252, b: felt252) -> bool { - b < a + fn gt(lhs: felt252, rhs: felt252) -> bool { + rhs < lhs } } diff --git a/exercises/structs/README.md b/exercises/structs/README.md index 19787a1f3..8a1da9f69 100644 --- a/exercises/structs/README.md +++ b/exercises/structs/README.md @@ -12,4 +12,6 @@ struct Rectangle { ## Further information -- [Structures](https://medium.com/nethermind-eth/a-first-look-at-cairo-1-0-a-safer-stronger-simpler-provable-programming-language-892ce4c07b38#ff54] +- [Defining and instanciating Structs](https://cairo-book.github.io/ch04-01-defining-and-instantiating-structs.html) +- [An example program using structs](https://cairo-book.github.io/ch04-02-an-example-program-using-structs.html) +- [The Method syntax](https://cairo-book.github.io/ch04-03-method-syntax.html) diff --git a/exercises/traits/README.md b/exercises/traits/README.md index 5efe32b98..b5ba456d5 100644 --- a/exercises/traits/README.md +++ b/exercises/traits/README.md @@ -8,4 +8,4 @@ In this way, traits are somewhat similar to Java interfaces and C++ abstract cla Because traits indicate shared behavior between data types, they are useful when writing generics. -- [Traits & Impls](https://medium.com/nethermind-eth/a-first-look-at-cairo-1-0-a-safer-stronger-simpler-provable-programming-language-892ce4c07b38#83b5) +- [Traits & Impls](https://cairo-book.github.io/ch07-02-traits-in-cairo.html) diff --git a/exercises/variables/README.md b/exercises/variables/README.md index 042394451..17e96397a 100644 --- a/exercises/variables/README.md +++ b/exercises/variables/README.md @@ -9,5 +9,5 @@ It is however important to clarify the fact that even though the variable can be ## Further information - [Memory model (from Cairo 0)](https://www.cairo-lang.org/docs/how_cairo_works/cairo_intro.html#memory-model) -- [Variables](https://medium.com/nethermind-eth/a-first-look-at-cairo-1-0-a-safer-stronger-simpler-provable-programming-language-892ce4c07b38#4fe8) -- [Integer types](https://medium.com/nethermind-eth/a-first-look-at-cairo-1-0-a-safer-stronger-simpler-provable-programming-language-892ce4c07b38#6d64) +- [Variables](https://cairo-book.github.io/ch02-01-variables-and-mutability.html) +- [Integer types](https://cairo-book.github.io/ch02-02-data-types.html#integer-types) diff --git a/info.toml b/info.toml index ba1fbca55..bf5ea1bf9 100644 --- a/info.toml +++ b/info.toml @@ -218,6 +218,24 @@ path = "exercises/quizs/quizs1.cairo" mode = "test" hint = """No hints this time ;)""" +# LOOPS + +[[exercises]] +name = "loops1" +path = "exercises/loops/loops1.cairo" +mode = "test" +hint = """ +The `break` condition is reached too early. Can you introduce a condition so that the loop runs a little more?""" + +[[exercises]] +name = "loops2" +path = "exercises/loops/loops2.cairo" +mode = "test" +hint = """ +You can return values from loops by adding the value you want returned after the `break` expression you use to stop the loop. Don't forget that assigning a variable to the value returned from a `loop` is an expression, and thus must end with a semicolomn. +""" + + # ENUMS [[exercises]] diff --git a/src/exercise.rs b/src/exercise.rs index 695ded75a..09187cbb5 100755 --- a/src/exercise.rs +++ b/src/exercise.rs @@ -110,8 +110,9 @@ impl Exercise { } pub fn state(&self) -> State { - let mut source_file = File::open(&self.path).unwrap_or_else(|_| panic!("We were unable to open the exercise file! {:?}", - self.path)); + let mut source_file = File::open(&self.path).unwrap_or_else(|_| { + panic!("We were unable to open the exercise file! {:?}", self.path) + }); let source = { let mut s = String::new(); diff --git a/src/main.rs b/src/main.rs index 16f7d6209..632805613 100755 --- a/src/main.rs +++ b/src/main.rs @@ -294,9 +294,7 @@ fn main() { Subcommands::Watch(_subargs) => match watch(&exercises) { Err(e) => { - println!( - "Error: Could not watch your progress. Error message was {e:?}." - ); + println!("Error: Could not watch your progress. Error message was {e:?}."); println!("Most likely you've run out of disk space or your 'inotify limit' has been reached."); std::process::exit(1); } diff --git a/src/starklings_runner.rs b/src/starklings_runner.rs index 8097f8680..44219cf2f 100644 --- a/src/starklings_runner.rs +++ b/src/starklings_runner.rs @@ -42,18 +42,18 @@ fn main() -> anyhow::Result<()> { } pub fn run_cairo_program(args: &Args) -> anyhow::Result { - let mut db = RootDatabase::default(); + let db = &mut RootDatabase::builder().build()?; let mut corelib_dir = std::env::current_exe() .unwrap_or_else(|e| panic!("Problem getting the executable path: {e:?}")); corelib_dir.pop(); corelib_dir.pop(); corelib_dir.pop(); corelib_dir.push(CORELIB_DIR_NAME); - init_dev_corelib(&mut db, corelib_dir); + init_dev_corelib(db, corelib_dir); - let main_crate_ids = setup_project(&mut db, Path::new(&args.path))?; + let main_crate_ids = setup_project(db, Path::new(&args.path))?; - if DiagnosticsReporter::stderr().check(&mut db) { + if DiagnosticsReporter::stderr().check(db) { anyhow::bail!("failed to compile: {}", args.path); } @@ -64,8 +64,12 @@ pub fn run_cairo_program(args: &Args) -> anyhow::Result { .to_option() .with_context(|| "Compilation failed without any diagnostics.")?; let runner = SierraCasmRunner::new( - replace_sierra_ids_in_program(&mut db, &sierra_program), - args.available_gas.is_some(), + replace_sierra_ids_in_program(db, &sierra_program), + if args.available_gas.is_some() { + Some(Default::default()) + } else { + None + }, ) .with_context(|| "Failed setting up runner.")?; let result = runner diff --git a/src/starklings_tester.rs b/src/starklings_tester.rs index c9e728c7e..d536458be 100644 --- a/src/starklings_tester.rs +++ b/src/starklings_tester.rs @@ -1,36 +1,50 @@ //! Compiles and runs a Cairo program. -use std::collections::HashSet; use std::path::Path; use std::sync::{Arc, Mutex}; use anyhow::{bail, Context}; +use cairo_felt::Felt252; use cairo_lang_compiler::db::RootDatabase; use cairo_lang_compiler::diagnostics::DiagnosticsReporter; use cairo_lang_compiler::project::setup_project; use cairo_lang_debug::DebugWithDb; use cairo_lang_defs::ids::{FreeFunctionId, FunctionWithBodyId, ModuleItemId}; +use cairo_lang_defs::plugin::PluginDiagnostic; use cairo_lang_diagnostics::ToOption; +use cairo_lang_filesystem::cfg::{Cfg, CfgSet}; use cairo_lang_filesystem::db::init_dev_corelib; use cairo_lang_filesystem::ids::CrateId; -use cairo_lang_plugins::config::ConfigPlugin; -use cairo_lang_plugins::derive::DerivePlugin; -use cairo_lang_plugins::panicable::PanicablePlugin; +use cairo_lang_plugins::get_default_plugins; + +use cairo_lang_lowering::ids::ConcreteFunctionWithBodyId; use cairo_lang_runner::short_string::as_cairo_short_string; use cairo_lang_runner::{RunResultValue, SierraCasmRunner}; use cairo_lang_semantic::db::SemanticGroup; use cairo_lang_semantic::items::functions::GenericFunctionId; +use cairo_lang_semantic::literals::LiteralLongId; use cairo_lang_semantic::plugin::SemanticPlugin; -use cairo_lang_semantic::{ConcreteFunction, ConcreteFunctionWithBodyId, FunctionLongId}; +use cairo_lang_semantic::{ConcreteFunction, FunctionLongId}; +use cairo_lang_sierra::extensions::gas::CostTokenType; +use cairo_lang_sierra::ids::FunctionId; use cairo_lang_sierra_generator::db::SierraGenGroup; use cairo_lang_sierra_generator::replace_ids::replace_sierra_ids_in_program; +use cairo_lang_sierra_to_casm::metadata::MetadataComputationConfig; +use cairo_lang_starknet::casm_contract_class::ENTRY_POINT_COST; +use cairo_lang_starknet::contract::{find_contracts, get_module_functions}; +use cairo_lang_starknet::plugin::consts::{CONSTRUCTOR_MODULE, EXTERNAL_MODULE, L1_HANDLER_MODULE}; use cairo_lang_starknet::plugin::StarkNetPlugin; -use cairo_lang_syntax::node::ast::Expr; -use cairo_lang_syntax::node::Token; +use cairo_lang_syntax::attribute::structured::{Attribute, AttributeArg, AttributeArgVariant}; + +use cairo_lang_syntax::node::db::SyntaxGroup; +use cairo_lang_syntax::node::{ast, Terminal, Token}; +use cairo_lang_utils::ordered_hash_map::OrderedHashMap; +use cairo_lang_utils::OptionHelper; use clap::Parser; use colored::Colorize; -use itertools::Itertools; +use itertools::{chain, Itertools}; use rayon::prelude::{IntoParallelIterator, ParallelIterator}; +use unescaper::unescape; const CORELIB_DIR_NAME: &str = "corelib/src"; @@ -75,17 +89,16 @@ fn main() -> anyhow::Result<()> { pub fn test_cairo_program(args: &Args) -> anyhow::Result { // TODO(orizi): Use `get_default_plugins` and just update the config plugin. - let mut plugins: Vec> = vec![ - Arc::new(DerivePlugin {}), - Arc::new(PanicablePlugin {}), - Arc::new(ConfigPlugin { - configs: HashSet::from(["test".to_string()]), - }), - ]; + let mut plugins: Vec> = get_default_plugins(); if args.starknet { - plugins.push(Arc::new(StarkNetPlugin {})); + plugins.push(Arc::new(StarkNetPlugin::default())); } - let db = &mut RootDatabase::builder().with_plugins(plugins).build()?; + let db = &mut RootDatabase::builder() + .with_cfg(CfgSet::from_iter([Cfg::name("test")])) + .with_plugins(plugins) + .detect_corelib() + .build()?; + let mut corelib_dir = std::env::current_exe() .unwrap_or_else(|e| panic!("Problem getting the executable path: {e:?}")); corelib_dir.pop(); @@ -99,21 +112,51 @@ pub fn test_cairo_program(args: &Args) -> anyhow::Result { if DiagnosticsReporter::stderr().check(db) { bail!("failed to compile: {}", args.path); } + let all_entry_points = if args.starknet { + find_contracts(db, &main_crate_ids) + .iter() + .flat_map(|contract| { + chain!( + get_module_functions(db, contract, EXTERNAL_MODULE).unwrap(), + get_module_functions(db, contract, CONSTRUCTOR_MODULE).unwrap(), + get_module_functions(db, contract, L1_HANDLER_MODULE).unwrap() + ) + }) + .flat_map(|func_id| ConcreteFunctionWithBodyId::from_no_generics_free(db, func_id)) + .collect() + } else { + vec![] + }; + let function_set_costs: OrderedHashMap> = + all_entry_points + .iter() + .map(|func_id| { + ( + db.function_with_body_sierra(*func_id).unwrap().id.clone(), + [(CostTokenType::Const, ENTRY_POINT_COST)].into(), + ) + }) + .collect(); let all_tests = find_all_tests(db, main_crate_ids); + let sierra_program = db .get_sierra_program_for_functions( - all_tests - .iter() - .flat_map(|t| ConcreteFunctionWithBodyId::from_no_generics_free(db, t.func_id)) - .collect(), + chain!( + all_entry_points.into_iter(), + all_tests.iter().flat_map(|(func_id, _cfg)| { + ConcreteFunctionWithBodyId::from_no_generics_free(db, *func_id) + }) + ) + .collect(), ) .to_option() .with_context(|| "Compilation failed without any diagnostics.")?; let sierra_program = replace_sierra_ids_in_program(db, &sierra_program); let total_tests_count = all_tests.len(); + let named_tests = all_tests .into_iter() - .map(|mut test| { + .map(|(func_id, mut test)| { // Un-ignoring all the tests in `include-ignored` mode. if args.include_ignored { test.ignored = false; @@ -123,8 +166,8 @@ pub fn test_cairo_program(args: &Args) -> anyhow::Result { "{:?}", FunctionLongId { function: ConcreteFunction { - generic_function: GenericFunctionId::Free(test.func_id), - generic_args: vec![], + generic_function: GenericFunctionId::Free(func_id), + generic_args: vec![] } } .debug(db) @@ -142,7 +185,7 @@ pub fn test_cairo_program(args: &Args) -> anyhow::Result { failed, ignored, failed_run_results, - } = run_tests(named_tests, sierra_program)?; + } = run_tests(named_tests, sierra_program, function_set_costs)?; let mut result_string = String::new(); if failed.is_empty() { result_string.push_str( @@ -162,8 +205,11 @@ pub fn test_cairo_program(args: &Args) -> anyhow::Result { result_string.push_str(format!(" {failure} - ").as_str()); match run_result { RunResultValue::Success(_) => { - result_string - .push_str("expected panic but finished successfully.".to_string().as_str()); + result_string.push_str( + "expected panic but finished successfully." + .to_string() + .as_str(), + ); } RunResultValue::Panic(values) => { result_string.push_str("panicked with [".to_string().as_str()); @@ -203,9 +249,13 @@ struct TestsSummary { fn run_tests( named_tests: Vec<(String, TestConfig)>, sierra_program: cairo_lang_sierra::program::Program, + function_set_costs: OrderedHashMap>, ) -> anyhow::Result { - let runner = - SierraCasmRunner::new(sierra_program, true).with_context(|| "Failed setting up runner.")?; + let runner = SierraCasmRunner::new( + sierra_program, + Some(MetadataComputationConfig { function_set_costs }), + ) + .with_context(|| "Failed setting up runner.")?; println!("running {} tests", named_tests.len()); let wrapped_summary = Mutex::new(Ok(TestsSummary { passed: vec![], @@ -221,16 +271,23 @@ fn run_tests( } let result = runner .run_function(name.as_str(), &[], test.available_gas) - .with_context(|| "Failed to run the function.")?; + .with_context(|| format!("Failed to run the function `{}`.", name.as_str()))?; Ok(( name, - match (&result.value, test.expectation) { - (RunResultValue::Success(_), TestExpectation::Success) - | (RunResultValue::Panic(_), TestExpectation::Panics) => TestStatus::Success, - (RunResultValue::Success(_), TestExpectation::Panics) - | (RunResultValue::Panic(_), TestExpectation::Success) => { - TestStatus::Fail(result.value) - } + match &result.value { + RunResultValue::Success(_) => match test.expectation { + TestExpectation::Success => TestStatus::Success, + TestExpectation::Panics(_) => TestStatus::Fail(result.value), + }, + RunResultValue::Panic(value) => match test.expectation { + TestExpectation::Success => TestStatus::Fail(result.value), + TestExpectation::Panics(panic_expectation) => match panic_expectation { + PanicExpectation::Exact(expected) if value != &expected => { + TestStatus::Fail(result.value) + } + _ => TestStatus::Success, + }, + }, }, )) }) @@ -260,29 +317,35 @@ fn run_tests( }); wrapped_summary.into_inner().unwrap() } +/// Expectation for a panic case. +pub enum PanicExpectation { + /// Accept any panic value. + Any, + /// Accept only this specific vector of panics. + Exact(Vec), +} /// Expectation for a result of a test. -enum TestExpectation { +pub enum TestExpectation { /// Running the test should not panic. Success, /// Running the test should result in a panic. - Panics, + Panics(PanicExpectation), } - /// The configuration for running a single test. -struct TestConfig { - /// The function id of the test function. - func_id: FreeFunctionId, +pub struct TestConfig { /// The amount of gas the test requested. - available_gas: Option, + pub available_gas: Option, /// The expected result of the run. - expectation: TestExpectation, + pub expectation: TestExpectation, /// Should the test be ignored. - ignored: bool, + pub ignored: bool, } - /// Finds the tests in the requested crates. -fn find_all_tests(db: &dyn SemanticGroup, main_crates: Vec) -> Vec { +fn find_all_tests( + db: &dyn SemanticGroup, + main_crates: Vec, +) -> Vec<(FreeFunctionId, TestConfig)> { let mut tests = vec![]; for crate_id in main_crates { let modules = db.crate_modules(crate_id); @@ -290,56 +353,147 @@ fn find_all_tests(db: &dyn SemanticGroup, main_crates: Vec) -> Vec { - is_test = true; - } - "available_gas" => { - // TODO(orizi): Provide diagnostics when this does not match. - if let [Expr::Literal(literal)] = &attr.args[..] { - available_gas = literal - .token(db.upcast()) - .text(db.upcast()) - .parse::() - .ok(); - } - } - "should_panic" => { - should_panic = true; - } - "ignore" => { - ignored = true; - } - _ => {} - } - } - if is_test { - tests.push(TestConfig { - func_id: *func_id, - available_gas, - expectation: if should_panic { - TestExpectation::Panics - } else { - TestExpectation::Success - }, - ignored, - }) - } - } - } - } + tests.extend( + module_items.iter().filter_map(|item| { + let ModuleItemId::FreeFunction(func_id) = item else { return None }; + let Ok(attrs) = db.function_with_body_attributes(FunctionWithBodyId::Free(*func_id)) else { return None }; + Some((*func_id, try_extract_test_config(db.upcast(), attrs).unwrap()?)) + }), + ); } } tests } + +/// Extracts the configuration of a tests from attributes, or returns the diagnostics if the +/// attributes are set illegally. +pub fn try_extract_test_config( + db: &dyn SyntaxGroup, + attrs: Vec, +) -> Result, Vec> { + let test_attr = attrs.iter().find(|attr| attr.id.as_str() == "test"); + let ignore_attr = attrs.iter().find(|attr| attr.id.as_str() == "ignore"); + let available_gas_attr = attrs + .iter() + .find(|attr| attr.id.as_str() == "available_gas"); + let should_panic_attr = attrs.iter().find(|attr| attr.id.as_str() == "should_panic"); + let mut diagnostics = vec![]; + if let Some(attr) = test_attr { + if !attr.args.is_empty() { + diagnostics.push(PluginDiagnostic { + stable_ptr: attr.id_stable_ptr.untyped(), + message: "Attribute should not have arguments.".into(), + }); + } + } else { + for attr in [ignore_attr, available_gas_attr, should_panic_attr] + .into_iter() + .flatten() + { + diagnostics.push(PluginDiagnostic { + stable_ptr: attr.id_stable_ptr.untyped(), + message: "Attribute should only appear on tests.".into(), + }); + } + } + let ignored = if let Some(attr) = ignore_attr { + if !attr.args.is_empty() { + diagnostics.push(PluginDiagnostic { + stable_ptr: attr.id_stable_ptr.untyped(), + message: "Attribute should not have arguments.".into(), + }); + } + true + } else { + false + }; + let available_gas = if let Some(attr) = available_gas_attr { + if let [AttributeArg { + variant: + AttributeArgVariant::Unnamed { + value: ast::Expr::Literal(literal), + .. + }, + .. + }] = &attr.args[..] + { + literal.token(db).text(db).parse::().ok() + } else { + diagnostics.push(PluginDiagnostic { + stable_ptr: attr.id_stable_ptr.untyped(), + message: "Attribute should have a single value argument.".into(), + }); + None + } + } else { + None + }; + let (should_panic, expected_panic_value) = if let Some(attr) = should_panic_attr { + if attr.args.is_empty() { + (true, None) + } else { + ( + true, + extract_panic_values(db, attr).on_none(|| { + diagnostics.push(PluginDiagnostic { + stable_ptr: attr.args_stable_ptr.untyped(), + message: "Expected panic must be of the form `expected = `." + .into(), + }); + }), + ) + } + } else { + (false, None) + }; + if !diagnostics.is_empty() { + return Err(diagnostics); + } + Ok(if test_attr.is_none() { + None + } else { + Some(TestConfig { + available_gas, + expectation: if should_panic { + TestExpectation::Panics(if let Some(values) = expected_panic_value { + PanicExpectation::Exact(values) + } else { + PanicExpectation::Any + }) + } else { + TestExpectation::Success + }, + ignored, + }) + }) +} +/// Tries to extract the relevant expected panic values. +fn extract_panic_values(db: &dyn SyntaxGroup, attr: &Attribute) -> Option> { + let [ + AttributeArg { + variant: AttributeArgVariant::Named { name, value: panics, .. }, + .. + } + ] = &attr.args[..] else { + return None; + }; + if name != "expected" { + return None; + } + let ast::Expr::Tuple(panics) = panics else { return None }; + panics + .expressions(db) + .elements(db) + .into_iter() + .map(|value| match value { + ast::Expr::Literal(literal) => { + Some(literal.numeric_value(db).unwrap_or_default().into()) + } + ast::Expr::ShortString(literal) => { + Some(literal.numeric_value(db).unwrap_or_default().into()) + } + _ => None, + }) + .collect::>>() +} diff --git a/src/verify.rs b/src/verify.rs index 7b34e024a..1e292304f 100755 --- a/src/verify.rs +++ b/src/verify.rs @@ -65,10 +65,7 @@ fn compile_and_test_interactively(exercise: &Exercise) -> Result { // Compile the given Exercise and return an object with information // about the state of the compilation -fn compile_and_run_cairo<'a, 'b>( - exercise: &'a Exercise, - progress_bar: &'b ProgressBar, -) -> Result { +fn compile_and_run_cairo(exercise: &Exercise, progress_bar: &ProgressBar) -> Result { let compilation_result = exercise.run_cairo(); if let Some(error) = compilation_result.as_ref().err() { @@ -86,10 +83,7 @@ fn compile_and_run_cairo<'a, 'b>( // Tests the given Exercise and return an object with information // about the state of the tests -fn compile_and_test_cairo<'a, 'b>( - exercise: &'a Exercise, - progress_bar: &'b ProgressBar, -) -> Result { +fn compile_and_test_cairo(exercise: &Exercise, progress_bar: &ProgressBar) -> Result { let compilation_result = exercise.test_cairo(); if let Some(error) = compilation_result.as_ref().err() { diff --git a/tests/integration_tests.rs b/tests/integration_tests.rs index 1a9bfe20d..74198aa45 100755 --- a/tests/integration_tests.rs +++ b/tests/integration_tests.rs @@ -57,11 +57,7 @@ fn all_exercises_require_confirmation() { source .matches("// I AM NOT DONE") .next() - .unwrap_or_else(|| { - panic!( - "There should be an `I AM NOT DONE` annotation in {path:?}" - ) - }); + .unwrap_or_else(|| panic!("There should be an `I AM NOT DONE` annotation in {path:?}")); } }