From 719d67197066d3369a5693d9b2a8ed8a90b5ab66 Mon Sep 17 00:00:00 2001 From: Shramee Srivastav Date: Mon, 19 Feb 2024 14:42:15 +0800 Subject: [PATCH] updating to scarb 2.5.3 (#188) --- Cargo.lock | 1702 +++++++++++++------ Cargo.toml | 12 +- corelib/Scarb.lock | 2 +- corelib/Scarb.toml | 3 +- corelib/cairo_project.toml | 6 + corelib/src/array.cairo | 65 +- corelib/src/boolean.cairo | 19 + corelib/src/box.cairo | 18 +- corelib/src/byte_array.cairo | 54 +- corelib/src/bytes_31.cairo | 62 +- corelib/src/clone.cairo | 3 +- corelib/src/cmp.cairo | 6 +- corelib/src/debug.cairo | 50 +- corelib/src/dict.cairo | 17 +- corelib/src/ec.cairo | 33 +- corelib/src/ecdsa.cairo | 17 +- corelib/src/felt_252.cairo | 31 + corelib/src/fmt.cairo | 204 +++ corelib/src/gas.cairo | 10 +- corelib/src/hash.cairo | 23 +- corelib/src/integer.cairo | 893 +++++++--- corelib/src/internal.cairo | 9 +- corelib/src/keccak.cairo | 30 +- corelib/src/lib.cairo | 110 +- corelib/src/math.cairo | 154 +- corelib/src/metaprogramming.cairo | 5 + corelib/src/nullable.cairo | 58 +- corelib/src/num.cairo | 1 + corelib/src/num/traits.cairo | 8 + corelib/src/num/traits/bit_size.cairo | 6 + corelib/src/num/traits/one.cairo | 9 + corelib/src/num/traits/zero.cairo | 9 + corelib/src/option.cairo | 48 +- corelib/src/panics.cairo | 17 +- corelib/src/pedersen.cairo | 14 +- corelib/src/poseidon.cairo | 36 +- corelib/src/prelude.cairo | 2 + corelib/src/prelude/v2023_01.cairo | 70 + corelib/src/prelude/v2023_10.cairo | 27 + corelib/src/result.cairo | 33 +- corelib/src/serde.cairo | 12 +- corelib/src/starknet.cairo | 77 +- corelib/src/starknet/account.cairo | 12 +- corelib/src/starknet/class_hash.cairo | 37 +- corelib/src/starknet/contract_address.cairo | 58 +- corelib/src/starknet/eth_address.cairo | 36 +- corelib/src/starknet/eth_signature.cairo | 16 +- corelib/src/starknet/event.cairo | 6 +- corelib/src/starknet/info.cairo | 116 +- corelib/src/starknet/secp256_trait.cairo | 38 +- corelib/src/starknet/secp256k1.cairo | 8 +- corelib/src/starknet/secp256r1.cairo | 8 +- corelib/src/starknet/storage.cairo | 20 +- corelib/src/starknet/storage_access.cairo | 557 +++--- corelib/src/starknet/syscalls.cairo | 24 +- corelib/src/starknet/testing.cairo | 45 +- corelib/src/string.cairo | 2 +- corelib/src/test.cairo | 8 + corelib/src/test/array_test.cairo | 50 +- corelib/src/test/bool_test.cairo | 2 +- corelib/src/test/box_test.cairo | 2 +- corelib/src/test/byte_array_test.cairo | 117 +- corelib/src/test/bytes31_test.cairo | 58 +- corelib/src/test/cmp_test.cairo | 4 +- corelib/src/test/dict_test.cairo | 68 +- corelib/src/test/ec_test.cairo | 10 +- corelib/src/test/felt_test.cairo | 2 +- corelib/src/test/fmt_test.cairo | 80 + corelib/src/test/hash_test.cairo | 15 +- corelib/src/test/integer_test.cairo | 363 +++- corelib/src/test/keccak_test.cairo | 10 +- corelib/src/test/math_test.cairo | 139 +- corelib/src/test/nullable_test.cairo | 31 + corelib/src/test/num_test.cairo | 17 + corelib/src/test/panics_test.cairo | 146 ++ corelib/src/test/plugins_test.cairo | 89 +- corelib/src/test/print_test.cairo | 131 ++ corelib/src/test/result_test.cairo | 125 ++ corelib/src/test/secp256k1_test.cairo | 13 +- corelib/src/test/secp256r1_test.cairo | 8 +- corelib/src/test/test_utils.cairo | 12 +- corelib/src/test/testing_test.cairo | 62 +- corelib/src/test/to_byte_array_test.cairo | 11 +- corelib/src/testing.cairo | 2 +- corelib/src/to_byte_array.cairo | 48 +- corelib/src/traits.cairo | 71 +- corelib/src/zeroable.cairo | 64 +- src/scarb.rs | 6 +- 88 files changed, 4699 insertions(+), 2013 deletions(-) create mode 100644 corelib/src/boolean.cairo create mode 100644 corelib/src/felt_252.cairo create mode 100644 corelib/src/fmt.cairo create mode 100644 corelib/src/metaprogramming.cairo create mode 100644 corelib/src/num.cairo create mode 100644 corelib/src/num/traits.cairo create mode 100644 corelib/src/num/traits/bit_size.cairo create mode 100644 corelib/src/num/traits/one.cairo create mode 100644 corelib/src/num/traits/zero.cairo create mode 100644 corelib/src/prelude.cairo create mode 100644 corelib/src/prelude/v2023_01.cairo create mode 100644 corelib/src/prelude/v2023_10.cairo create mode 100644 corelib/src/test/fmt_test.cairo create mode 100644 corelib/src/test/nullable_test.cairo create mode 100644 corelib/src/test/num_test.cairo create mode 100644 corelib/src/test/panics_test.cairo create mode 100644 corelib/src/test/print_test.cairo create mode 100644 corelib/src/test/result_test.cairo diff --git a/Cargo.lock b/Cargo.lock index 4b50c9649..a0ae5f9d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -30,14 +30,15 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.3" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" dependencies = [ "cfg-if 1.0.0", "getrandom", "once_cell", "version_check", + "zerocopy", ] [[package]] @@ -149,7 +150,7 @@ dependencies = [ "argh_shared", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.43", ] [[package]] @@ -354,7 +355,7 @@ checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.43", ] [[package]] @@ -513,16 +514,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3e368af43e418a04d52505cf3dbc23dda4e3407ae2fa99fd0e4f308ce546acc" [[package]] -name = "byteyarn" -version = "0.2.3" +name = "cairo-felt" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7534301c0ea17abb4db06d75efc7b4b0fa360fce8e175a4330d721c71c942ff" +checksum = "5972097b8800ca5dffb458040e74c724a2ac4fa4b5b480b50f5b96c7e67d6427" +dependencies = [ + "lazy_static", + "num-bigint", + "num-integer", + "num-traits 0.2.16", + "serde", +] [[package]] name = "cairo-felt" -version = "0.8.7" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5972097b8800ca5dffb458040e74c724a2ac4fa4b5b480b50f5b96c7e67d6427" +checksum = "ae932292b9ba497a4e892b56aa4e0c6f329a455180fdbdc132700dfe68d9b153" dependencies = [ "lazy_static", "num-bigint", @@ -533,62 +541,120 @@ dependencies = [ [[package]] name = "cairo-lang-casm" -version = "2.3.0" -source = "git+https://github.com/starkware-libs/cairo?rev=bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f#bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc54b38b6784e2a050c725802d4b5a5634bad32119f8a0a67fccf98e8d5a9f7b" dependencies = [ - "cairo-lang-utils", + "cairo-lang-utils 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "indoc", + "num-bigint", + "num-traits 0.2.16", + "parity-scale-codec", + "serde", +] + +[[package]] +name = "cairo-lang-casm" +version = "2.5.3" +source = "git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31#7bf91178ad4a775943da53f1dab94068e5d70e31" +dependencies = [ + "cairo-lang-utils 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", "indoc", "num-bigint", "num-traits 0.2.16", "parity-scale-codec", - "parity-scale-codec-derive", - "schemars", "serde", +] + +[[package]] +name = "cairo-lang-compiler" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "816a6e69bcb48f40513592cebfe5ee80472c93d3dfd4793eaa09d8e2c4dd5489" +dependencies = [ + "anyhow", + "cairo-lang-defs 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-diagnostics 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-filesystem 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-lowering 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-parser 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-project 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-semantic 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-sierra 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-sierra-generator 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-syntax 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-utils 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "salsa", "thiserror", ] [[package]] name = "cairo-lang-compiler" -version = "2.3.0" -source = "git+https://github.com/starkware-libs/cairo?rev=bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f#bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f" +version = "2.5.3" +source = "git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31#7bf91178ad4a775943da53f1dab94068e5d70e31" dependencies = [ "anyhow", - "cairo-lang-defs", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-lowering", - "cairo-lang-parser", - "cairo-lang-plugins", - "cairo-lang-project", - "cairo-lang-semantic", - "cairo-lang-sierra", - "cairo-lang-sierra-generator", - "cairo-lang-syntax", - "cairo-lang-utils", - "itertools 0.11.0", + "cairo-lang-defs 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-diagnostics 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-filesystem 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-lowering 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-parser 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-project 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-semantic 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-sierra 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-sierra-generator 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-syntax 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-utils 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", "salsa", + "smol_str", "thiserror", ] [[package]] name = "cairo-lang-debug" -version = "2.3.0" -source = "git+https://github.com/starkware-libs/cairo?rev=bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f#bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bee329295640812932a5ca71552d97cfe2057e2d2ef23a6328393c312c7f5367" +dependencies = [ + "cairo-lang-utils 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cairo-lang-debug" +version = "2.5.3" +source = "git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31#7bf91178ad4a775943da53f1dab94068e5d70e31" +dependencies = [ + "cairo-lang-utils 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", +] + +[[package]] +name = "cairo-lang-defs" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f08a77ba3c274593f4cfe375b7ecde1353c8489fd8257daf2df85a459126c59a" dependencies = [ - "cairo-lang-utils", + "cairo-lang-debug 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-diagnostics 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-filesystem 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-parser 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-syntax 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-utils 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.11.0", + "salsa", + "smol_str", ] [[package]] name = "cairo-lang-defs" -version = "2.3.0" -source = "git+https://github.com/starkware-libs/cairo?rev=bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f#bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f" -dependencies = [ - "cairo-lang-debug", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-parser", - "cairo-lang-syntax", - "cairo-lang-utils", +version = "2.5.3" +source = "git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31#7bf91178ad4a775943da53f1dab94068e5d70e31" +dependencies = [ + "cairo-lang-debug 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-diagnostics 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-filesystem 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-parser 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-syntax 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-utils 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", "itertools 0.11.0", "salsa", "smol_str", @@ -596,31 +662,67 @@ dependencies = [ [[package]] name = "cairo-lang-diagnostics" -version = "2.3.0" -source = "git+https://github.com/starkware-libs/cairo?rev=bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f#bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d9db9eff39d5a91ec1d681d6e52012e5374270120ee55c222211440508e2234" +dependencies = [ + "cairo-lang-debug 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-filesystem 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-utils 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.11.0", +] + +[[package]] +name = "cairo-lang-diagnostics" +version = "2.5.3" +source = "git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31#7bf91178ad4a775943da53f1dab94068e5d70e31" dependencies = [ - "cairo-lang-debug", - "cairo-lang-filesystem", - "cairo-lang-utils", + "cairo-lang-debug 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-filesystem 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-utils 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", "itertools 0.11.0", ] [[package]] name = "cairo-lang-eq-solver" -version = "2.3.0" -source = "git+https://github.com/starkware-libs/cairo?rev=bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f#bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "674eb82142b08aea2bca9d711393baea265b64c8a8cbe3a5ae570d84882a4b31" +dependencies = [ + "cairo-lang-utils 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "good_lp", +] + +[[package]] +name = "cairo-lang-eq-solver" +version = "2.5.3" +source = "git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31#7bf91178ad4a775943da53f1dab94068e5d70e31" dependencies = [ - "cairo-lang-utils", + "cairo-lang-utils 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", "good_lp", ] [[package]] name = "cairo-lang-filesystem" -version = "2.3.0" -source = "git+https://github.com/starkware-libs/cairo?rev=bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f#bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb697f1d097eeb18ea28fc576c32ad867beade0b47ac2f95ca84026cec025808" +dependencies = [ + "cairo-lang-debug 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-utils 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "path-clean", + "salsa", + "serde", + "smol_str", +] + +[[package]] +name = "cairo-lang-filesystem" +version = "2.5.3" +source = "git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31#7bf91178ad4a775943da53f1dab94068e5d70e31" dependencies = [ - "cairo-lang-debug", - "cairo-lang-utils", + "cairo-lang-debug 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-utils 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", "path-clean", "salsa", "serde", @@ -629,39 +731,64 @@ dependencies = [ [[package]] name = "cairo-lang-formatter" -version = "2.3.0" -source = "git+https://github.com/starkware-libs/cairo?rev=bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f#bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f" +version = "2.5.3" +source = "git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31#7bf91178ad4a775943da53f1dab94068e5d70e31" dependencies = [ "anyhow", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-parser", - "cairo-lang-syntax", - "cairo-lang-utils", + "cairo-lang-diagnostics 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-filesystem 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-parser 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-syntax 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-utils 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", "diffy", "ignore", "itertools 0.11.0", "salsa", "serde", "smol_str", + "thiserror", +] + +[[package]] +name = "cairo-lang-lowering" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8306cb070322918f9cc18163eb9a847b437cfb2dbf37da5a04dbd41f26f9347e" +dependencies = [ + "cairo-lang-debug 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-defs 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-diagnostics 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-filesystem 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-parser 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-proc-macros 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-semantic 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-syntax 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-utils 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "id-arena", + "itertools 0.11.0", + "log", + "num-bigint", + "num-traits 0.2.16", + "once_cell", + "salsa", + "smol_str", ] [[package]] name = "cairo-lang-lowering" -version = "2.3.0" -source = "git+https://github.com/starkware-libs/cairo?rev=bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f#bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f" -dependencies = [ - "cairo-lang-debug", - "cairo-lang-defs", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-parser", - "cairo-lang-proc-macros", - "cairo-lang-semantic", - "cairo-lang-syntax", - "cairo-lang-utils", +version = "2.5.3" +source = "git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31#7bf91178ad4a775943da53f1dab94068e5d70e31" +dependencies = [ + "cairo-lang-debug 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-defs 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-diagnostics 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-filesystem 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-parser 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-proc-macros 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-semantic 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-syntax 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-utils 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", "id-arena", - "indexmap 2.0.2", "itertools 0.11.0", "log", "num-bigint", @@ -673,14 +800,15 @@ dependencies = [ [[package]] name = "cairo-lang-parser" -version = "2.3.0" -source = "git+https://github.com/starkware-libs/cairo?rev=bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f#bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f" -dependencies = [ - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-syntax", - "cairo-lang-syntax-codegen", - "cairo-lang-utils", +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "813b3fcfb3db7c137150fb135dc5fb5e8b2b0fcf1343c911e8f282ef6be4896c" +dependencies = [ + "cairo-lang-diagnostics 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-filesystem 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-syntax 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-syntax-codegen 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-utils 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "colored", "itertools 0.11.0", "num-bigint", @@ -690,17 +818,55 @@ dependencies = [ "unescaper", ] +[[package]] +name = "cairo-lang-parser" +version = "2.5.3" +source = "git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31#7bf91178ad4a775943da53f1dab94068e5d70e31" +dependencies = [ + "cairo-lang-diagnostics 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-filesystem 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-syntax 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-syntax-codegen 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-utils 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "colored", + "itertools 0.11.0", + "num-bigint", + "num-traits 0.2.16", + "salsa", + "smol_str", + "unescaper", +] + +[[package]] +name = "cairo-lang-plugins" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e301ea0102f57dd6df3365b44b28397efb68aba069cd218de4e0944bd9a5ff" +dependencies = [ + "cairo-lang-defs 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-diagnostics 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-filesystem 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-parser 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-syntax 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-utils 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "indent", + "indoc", + "itertools 0.11.0", + "salsa", + "smol_str", +] + [[package]] name = "cairo-lang-plugins" -version = "2.3.0" -source = "git+https://github.com/starkware-libs/cairo?rev=bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f#bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f" -dependencies = [ - "cairo-lang-defs", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-parser", - "cairo-lang-syntax", - "cairo-lang-utils", +version = "2.5.3" +source = "git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31#7bf91178ad4a775943da53f1dab94068e5d70e31" +dependencies = [ + "cairo-lang-defs 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-diagnostics 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-filesystem 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-parser 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-syntax 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-utils 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", "indent", "indoc", "itertools 0.11.0", @@ -710,68 +876,99 @@ dependencies = [ [[package]] name = "cairo-lang-proc-macros" -version = "2.3.0" -source = "git+https://github.com/starkware-libs/cairo?rev=bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f#bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85aa42c1206b5848bb9ea7e77885ab5196bddcabe55332cc584ced6af9dd459e" +dependencies = [ + "cairo-lang-debug 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "quote", + "syn 2.0.43", +] + +[[package]] +name = "cairo-lang-proc-macros" +version = "2.5.3" +source = "git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31#7bf91178ad4a775943da53f1dab94068e5d70e31" dependencies = [ - "cairo-lang-debug", + "cairo-lang-debug 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", "quote", - "syn 2.0.37", + "syn 2.0.43", ] [[package]] name = "cairo-lang-project" -version = "2.3.0" -source = "git+https://github.com/starkware-libs/cairo?rev=bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f#bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15cc3bfe213c0fd569e7ba2a82200d1d49b1c9677fd4f9426967070bb83489a0" +dependencies = [ + "cairo-lang-filesystem 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-utils 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "serde", + "smol_str", + "thiserror", + "toml 0.8.10", +] + +[[package]] +name = "cairo-lang-project" +version = "2.5.3" +source = "git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31#7bf91178ad4a775943da53f1dab94068e5d70e31" dependencies = [ - "cairo-lang-filesystem", - "cairo-lang-utils", + "cairo-lang-filesystem 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-utils 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", "serde", "smol_str", "thiserror", - "toml 0.7.8", + "toml 0.8.10", ] [[package]] name = "cairo-lang-runner" -version = "2.3.0" -source = "git+https://github.com/starkware-libs/cairo?rev=bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f#bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fa31a3ecabb2ecf900c4337e26e3d534ff4f0170183d96be3f72fcfb679ac3e" dependencies = [ "ark-ff", "ark-secp256k1", "ark-secp256r1", "ark-std 0.4.0", - "cairo-felt", - "cairo-lang-casm", - "cairo-lang-sierra", - "cairo-lang-sierra-ap-change", - "cairo-lang-sierra-gas", - "cairo-lang-sierra-to-casm", - "cairo-lang-sierra-type-size", - "cairo-lang-starknet", - "cairo-lang-utils", + "cairo-felt 0.9.1", + "cairo-lang-casm 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-sierra 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-sierra-ap-change 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-sierra-generator 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-sierra-to-casm 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-sierra-type-size 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-starknet 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-utils 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "cairo-vm", "itertools 0.11.0", "keccak", "num-bigint", "num-integer", "num-traits 0.2.16", + "smol_str", + "starknet-crypto", "thiserror", ] [[package]] name = "cairo-lang-semantic" -version = "2.3.0" -source = "git+https://github.com/starkware-libs/cairo?rev=bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f#bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f" -dependencies = [ - "cairo-lang-debug", - "cairo-lang-defs", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-parser", - "cairo-lang-proc-macros", - "cairo-lang-syntax", - "cairo-lang-utils", +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "926f9fa06acd2fceb74f5471ca9c0954acd15c74eaf7f162722748013de0aa7e" +dependencies = [ + "cairo-lang-debug 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-defs 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-diagnostics 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-filesystem 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-parser 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-plugins 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-proc-macros 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-syntax 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-utils 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "id-arena", + "indoc", "itertools 0.11.0", "num-bigint", "num-traits 0.2.16", @@ -780,13 +977,64 @@ dependencies = [ "smol_str", ] +[[package]] +name = "cairo-lang-semantic" +version = "2.5.3" +source = "git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31#7bf91178ad4a775943da53f1dab94068e5d70e31" +dependencies = [ + "cairo-lang-debug 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-defs 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-diagnostics 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-filesystem 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-parser 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-plugins 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-proc-macros 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-syntax 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-utils 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "id-arena", + "indoc", + "itertools 0.11.0", + "num-bigint", + "num-traits 0.2.16", + "once_cell", + "salsa", + "smol_str", +] + +[[package]] +name = "cairo-lang-sierra" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3af31e751df35f8be2be2d692ac027c9d08e91a0aa2c2aff702480535643ef7" +dependencies = [ + "anyhow", + "cairo-felt 0.9.1", + "cairo-lang-utils 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "const-fnv1a-hash", + "convert_case", + "derivative", + "itertools 0.11.0", + "lalrpop", + "lalrpop-util", + "num-bigint", + "num-traits 0.2.16", + "regex", + "salsa", + "serde", + "serde_json", + "sha3", + "smol_str", + "thiserror", +] + [[package]] name = "cairo-lang-sierra" -version = "2.3.0" -source = "git+https://github.com/starkware-libs/cairo?rev=bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f#bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f" +version = "2.5.3" +source = "git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31#7bf91178ad4a775943da53f1dab94068e5d70e31" dependencies = [ "anyhow", - "cairo-lang-utils", + "cairo-felt 0.9.1", + "cairo-lang-utils 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", "const-fnv1a-hash", "convert_case", "derivative", @@ -806,46 +1054,78 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-ap-change" -version = "2.3.0" -source = "git+https://github.com/starkware-libs/cairo?rev=bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f#bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e5d3e18db52e0c2d104bce9d4888c9bb5a0fc5cd87673151941219aaad2d9ce" dependencies = [ - "cairo-lang-eq-solver", - "cairo-lang-sierra", - "cairo-lang-sierra-type-size", - "cairo-lang-utils", + "cairo-lang-eq-solver 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-sierra 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-sierra-type-size 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-utils 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.11.0", + "num-traits 0.2.16", + "thiserror", +] + +[[package]] +name = "cairo-lang-sierra-ap-change" +version = "2.5.3" +source = "git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31#7bf91178ad4a775943da53f1dab94068e5d70e31" +dependencies = [ + "cairo-lang-eq-solver 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-sierra 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-sierra-type-size 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-utils 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "itertools 0.11.0", + "num-traits 0.2.16", "thiserror", ] [[package]] name = "cairo-lang-sierra-gas" -version = "2.3.0" -source = "git+https://github.com/starkware-libs/cairo?rev=bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f#bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bc79b2bf4bd56b273ea64125f45dca5dc8583d56bbf8fd4741551f611d4dc7f" dependencies = [ - "cairo-lang-eq-solver", - "cairo-lang-sierra", - "cairo-lang-sierra-type-size", - "cairo-lang-utils", + "cairo-lang-eq-solver 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-sierra 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-sierra-type-size 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-utils 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.11.0", + "num-traits 0.2.16", + "thiserror", +] + +[[package]] +name = "cairo-lang-sierra-gas" +version = "2.5.3" +source = "git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31#7bf91178ad4a775943da53f1dab94068e5d70e31" +dependencies = [ + "cairo-lang-eq-solver 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-sierra 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-sierra-type-size 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-utils 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "itertools 0.11.0", + "num-traits 0.2.16", "thiserror", ] [[package]] name = "cairo-lang-sierra-generator" -version = "2.3.0" -source = "git+https://github.com/starkware-libs/cairo?rev=bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f#bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f" -dependencies = [ - "cairo-lang-debug", - "cairo-lang-defs", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-lowering", - "cairo-lang-parser", - "cairo-lang-semantic", - "cairo-lang-sierra", - "cairo-lang-syntax", - "cairo-lang-utils", - "indexmap 2.0.2", +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d9ac96139db603c6f351f84a9473e49b6b8bd4036a5fd9179fe8ebcee98a886" +dependencies = [ + "cairo-lang-debug 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-defs 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-diagnostics 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-filesystem 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-lowering 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-parser 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-semantic 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-sierra 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-syntax 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-utils 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.11.0", "num-bigint", "once_cell", @@ -853,19 +1133,62 @@ dependencies = [ "smol_str", ] +[[package]] +name = "cairo-lang-sierra-generator" +version = "2.5.3" +source = "git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31#7bf91178ad4a775943da53f1dab94068e5d70e31" +dependencies = [ + "cairo-lang-debug 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-defs 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-diagnostics 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-filesystem 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-lowering 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-parser 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-semantic 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-sierra 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-syntax 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-utils 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "itertools 0.11.0", + "num-bigint", + "once_cell", + "salsa", + "smol_str", +] + +[[package]] +name = "cairo-lang-sierra-to-casm" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1952c5738d20715d11716ce63ce3e022fdf8563548e4fa84c8dd0379860ca675" +dependencies = [ + "assert_matches", + "cairo-felt 0.9.1", + "cairo-lang-casm 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-sierra 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-sierra-ap-change 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-sierra-gas 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-sierra-type-size 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-utils 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "indoc", + "itertools 0.11.0", + "num-bigint", + "num-traits 0.2.16", + "thiserror", +] + [[package]] name = "cairo-lang-sierra-to-casm" -version = "2.3.0" -source = "git+https://github.com/starkware-libs/cairo?rev=bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f#bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f" +version = "2.5.3" +source = "git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31#7bf91178ad4a775943da53f1dab94068e5d70e31" dependencies = [ "assert_matches", - "cairo-felt", - "cairo-lang-casm", - "cairo-lang-sierra", - "cairo-lang-sierra-ap-change", - "cairo-lang-sierra-gas", - "cairo-lang-sierra-type-size", - "cairo-lang-utils", + "cairo-felt 0.9.1", + "cairo-lang-casm 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-sierra 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-sierra-ap-change 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-sierra-gas 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-sierra-type-size 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-utils 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", "indoc", "itertools 0.11.0", "num-bigint", @@ -875,32 +1198,44 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-type-size" -version = "2.3.0" -source = "git+https://github.com/starkware-libs/cairo?rev=bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f#bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a404f3acbca36d70ac380098f738c217ef768b4089a5aaa1d3d9fa4e3ef0dfca" +dependencies = [ + "cairo-lang-sierra 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-utils 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cairo-lang-sierra-type-size" +version = "2.5.3" +source = "git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31#7bf91178ad4a775943da53f1dab94068e5d70e31" dependencies = [ - "cairo-lang-sierra", - "cairo-lang-utils", + "cairo-lang-sierra 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-utils 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", ] [[package]] name = "cairo-lang-starknet" -version = "2.3.0" -source = "git+https://github.com/starkware-libs/cairo?rev=bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f#bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e7a618278918fc83da465ea6c85028009dc386b91ce8ccdcd08c3045255b7ae" dependencies = [ "anyhow", - "cairo-felt", - "cairo-lang-casm", - "cairo-lang-compiler", - "cairo-lang-defs", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-lowering", - "cairo-lang-semantic", - "cairo-lang-sierra", - "cairo-lang-sierra-generator", - "cairo-lang-sierra-to-casm", - "cairo-lang-syntax", - "cairo-lang-utils", + "cairo-felt 0.9.1", + "cairo-lang-casm 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-compiler 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-defs 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-diagnostics 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-filesystem 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-lowering 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-plugins 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-semantic 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-sierra 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-sierra-generator 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-sierra-to-casm 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-syntax 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-utils 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "const_format", "convert_case", "indent", @@ -914,17 +1249,88 @@ dependencies = [ "serde_json", "sha3", "smol_str", + "starknet-crypto", + "thiserror", +] + +[[package]] +name = "cairo-lang-starknet" +version = "2.5.3" +source = "git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31#7bf91178ad4a775943da53f1dab94068e5d70e31" +dependencies = [ + "anyhow", + "cairo-felt 0.9.1", + "cairo-lang-compiler 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-defs 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-diagnostics 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-filesystem 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-lowering 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-plugins 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-semantic 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-sierra 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-sierra-generator 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-starknet-classes", + "cairo-lang-syntax 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-utils 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "const_format", + "indent", + "indoc", + "itertools 0.11.0", + "once_cell", + "serde", + "serde_json", + "smol_str", "thiserror", ] +[[package]] +name = "cairo-lang-starknet-classes" +version = "2.5.3" +source = "git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31#7bf91178ad4a775943da53f1dab94068e5d70e31" +dependencies = [ + "cairo-felt 0.9.1", + "cairo-lang-casm 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-sierra 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-sierra-to-casm 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-utils 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "convert_case", + "itertools 0.11.0", + "num-bigint", + "num-integer", + "num-traits 0.2.16", + "once_cell", + "serde", + "serde_json", + "sha3", + "smol_str", + "starknet-crypto", + "thiserror", +] + +[[package]] +name = "cairo-lang-syntax" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08063b53ae8bc5c2d30b2a32a1abf807ffc082fe5f297a61370e4e540857d1a" +dependencies = [ + "cairo-lang-debug 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-filesystem 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-utils 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "num-bigint", + "num-traits 0.2.16", + "salsa", + "smol_str", + "unescaper", +] + [[package]] name = "cairo-lang-syntax" -version = "2.3.0" -source = "git+https://github.com/starkware-libs/cairo?rev=bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f#bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f" +version = "2.5.3" +source = "git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31#7bf91178ad4a775943da53f1dab94068e5d70e31" dependencies = [ - "cairo-lang-debug", - "cairo-lang-filesystem", - "cairo-lang-utils", + "cairo-lang-debug 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-filesystem 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-utils 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", "num-bigint", "num-traits 0.2.16", "salsa", @@ -934,8 +1340,18 @@ dependencies = [ [[package]] name = "cairo-lang-syntax-codegen" -version = "2.3.0" -source = "git+https://github.com/starkware-libs/cairo?rev=bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f#bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dc563a3457190f1f9d371fbfbb67e7f99675c54dcf9cb2f260e5aecb5ed3a73" +dependencies = [ + "genco", + "xshell", +] + +[[package]] +name = "cairo-lang-syntax-codegen" +version = "2.5.3" +source = "git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31#7bf91178ad4a775943da53f1dab94068e5d70e31" dependencies = [ "genco", "xshell", @@ -943,23 +1359,52 @@ dependencies = [ [[package]] name = "cairo-lang-test-plugin" -version = "2.3.0" -source = "git+https://github.com/starkware-libs/cairo?rev=bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f#bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "889e2324b7969757e512e09f44eaecb94d9b3cc5892cd2b5649d81de9d750493" dependencies = [ "anyhow", - "cairo-felt", - "cairo-lang-compiler", - "cairo-lang-debug", - "cairo-lang-defs", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-lowering", - "cairo-lang-semantic", - "cairo-lang-sierra", - "cairo-lang-sierra-generator", - "cairo-lang-starknet", - "cairo-lang-syntax", - "cairo-lang-utils", + "cairo-felt 0.9.1", + "cairo-lang-compiler 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-debug 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-defs 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-diagnostics 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-filesystem 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-lowering 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-semantic 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-sierra 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-sierra-generator 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-starknet 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-syntax 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-utils 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "indoc", + "itertools 0.11.0", + "num-bigint", + "num-traits 0.2.16", + "serde", +] + +[[package]] +name = "cairo-lang-test-plugin" +version = "2.5.3" +source = "git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31#7bf91178ad4a775943da53f1dab94068e5d70e31" +dependencies = [ + "anyhow", + "cairo-felt 0.9.1", + "cairo-lang-compiler 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-debug 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-defs 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-diagnostics 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-filesystem 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-lowering 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-semantic 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-sierra 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-sierra-generator 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-starknet 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-starknet-classes", + "cairo-lang-syntax 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-utils 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "indoc", "itertools 0.11.0", "num-bigint", "num-traits 0.2.16", @@ -968,19 +1413,20 @@ dependencies = [ [[package]] name = "cairo-lang-test-runner" -version = "2.3.0" -source = "git+https://github.com/starkware-libs/cairo?rev=bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f#bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "987cd7b124ef3adb30467c96c39365ef4b95736c6315e55e6abaa3c5596acf48" dependencies = [ "anyhow", - "cairo-felt", - "cairo-lang-compiler", - "cairo-lang-filesystem", + "cairo-felt 0.9.1", + "cairo-lang-compiler 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-filesystem 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "cairo-lang-runner", - "cairo-lang-sierra", - "cairo-lang-sierra-to-casm", - "cairo-lang-starknet", - "cairo-lang-test-plugin", - "cairo-lang-utils", + "cairo-lang-sierra 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-sierra-to-casm 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-starknet 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-test-plugin 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-utils 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "colored", "itertools 0.11.0", "num-traits 0.2.16", @@ -989,16 +1435,31 @@ dependencies = [ [[package]] name = "cairo-lang-utils" -version = "2.3.0" -source = "git+https://github.com/starkware-libs/cairo?rev=bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f#bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80f3de16afa605c6cc491661bc2dab71da10b379af0fdb7176f4f27e08d6286e" +dependencies = [ + "hashbrown 0.14.3", + "indexmap 2.2.2", + "itertools 0.11.0", + "num-bigint", + "num-traits 0.2.16", + "schemars", + "serde", +] + +[[package]] +name = "cairo-lang-utils" +version = "2.5.3" +source = "git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31#7bf91178ad4a775943da53f1dab94068e5d70e31" dependencies = [ "env_logger", - "indexmap 2.0.2", + "hashbrown 0.14.3", + "indexmap 2.2.2", "itertools 0.11.0", "log", "num-bigint", "num-traits 0.2.16", - "parity-scale-codec", "schemars", "serde", "time", @@ -1006,16 +1467,16 @@ dependencies = [ [[package]] name = "cairo-vm" -version = "0.8.7" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00d9bf139b0fe845627cf09d11af43eec9575dba702033bf6b08050c776b8553" +checksum = "fd569684da80d747273613d5c809e4f81bf6f6b1b64d0301b12bac8f2fb8ffb1" dependencies = [ "anyhow", "bincode", "bitvec", - "cairo-felt", + "cairo-felt 0.9.1", "generic-array", - "hashbrown 0.14.1", + "hashbrown 0.14.3", "hex", "keccak", "lazy_static", @@ -1031,6 +1492,7 @@ dependencies = [ "sha2", "sha3", "starknet-crypto", + "starknet-curve", "thiserror-no-std", ] @@ -1129,7 +1591,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.43", ] [[package]] @@ -1211,9 +1673,9 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ "core-foundation-sys", "libc", @@ -1221,9 +1683,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "cpufeatures" @@ -1246,7 +1708,7 @@ dependencies = [ [[package]] name = "create-output-dir" version = "1.0.0" -source = "git+https://github.com/software-mansion/scarb#7eb2819a2a2ad5ce8d1c3f760e3274a2ea576e60" +source = "git+https://github.com/software-mansion/scarb#5189ae09e2be80e5ed70c0f927b0bcd297454b5d" dependencies = [ "anyhow", "core-foundation", @@ -1390,7 +1852,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if 1.0.0", - "hashbrown 0.14.1", + "hashbrown 0.14.3", "lock_api", "once_cell", "parking_lot_core 0.9.8", @@ -1615,23 +2077,12 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "add4f07d43996f76ef320709726a556a9d4f965d9410d8d0271132d2f8293480" -dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ - "cc", "libc", + "windows-sys 0.52.0", ] [[package]] @@ -1648,9 +2099,9 @@ dependencies = [ [[package]] name = "faster-hex" -version = "0.8.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239f7bfb930f820ab16a9cd95afc26f88264cf6905c960b340a615384aa3338a" +checksum = "a2a2b11eda1d40935b26cf18f6833c526845ae8c41e58d09af6adeb6f0269183" dependencies = [ "serde", ] @@ -1721,9 +2172,9 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] @@ -1740,6 +2191,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + [[package]] name = "fsevent" version = "0.4.0" @@ -1837,7 +2294,7 @@ checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.43", ] [[package]] @@ -1872,9 +2329,9 @@ dependencies = [ [[package]] name = "genco" -version = "0.17.6" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3597f99dbe04460775cb349299b9532123980b17d89faeaa2da42658b7767787" +checksum = "98d7af598790738fee616426e669360fa361273b1b9c9b7f30c92fa627605cad" dependencies = [ "genco-macros", "relative-path", @@ -1883,13 +2340,13 @@ dependencies = [ [[package]] name = "genco-macros" -version = "0.17.6" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b029ca4c73c30f813e0e92754515585ccbede98014fb26644cc7488a3833706a" +checksum = "d4cf186fea4af17825116f72932fe52cce9a13bae39ff63b4dc0cfdb3fb4bde1" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.43", ] [[package]] @@ -1923,13 +2380,14 @@ checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "gix" -version = "0.54.1" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad6d32e74454459690d57d18ea4ebec1629936e6b130b51d12cb4a81630ac953" +checksum = "31887c304d9a935f3e5494fb5d6a0106c34e965168ec0db9b457424eedd0c741" dependencies = [ "gix-actor", "gix-archive", "gix-attributes", + "gix-command", "gix-commitgraph", "gix-config", "gix-credentials", @@ -1976,14 +2434,13 @@ dependencies = [ "signal-hook", "smallvec", "thiserror", - "unicode-normalization", ] [[package]] name = "gix-actor" -version = "0.27.0" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08c60e982c5290897122d4e2622447f014a2dadd5a18cb73d50bb91b31645e27" +checksum = "0a7bb9fad6125c81372987c06469601d37e1a2d421511adb69971b9083517a8a" dependencies = [ "bstr", "btoi", @@ -1995,9 +2452,9 @@ dependencies = [ [[package]] name = "gix-archive" -version = "0.5.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab71635f7fb38ad4cc7da7e98af79e3010e35b05de5cb6eb79b2da68ab93eac7" +checksum = "9b4d28c5375dd1a8a433ce0bb6d2a462182d853861d625cb43f0a821365ac020" dependencies = [ "bstr", "gix-date", @@ -2008,16 +2465,16 @@ dependencies = [ [[package]] name = "gix-attributes" -version = "0.19.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2451665e70709ba4753b623ef97511ee98c4a73816b2c5b5df25678d607ed820" +checksum = "214ee3792e504ee1ce206b36dcafa4f328ca313d1e2ac0b41433d68ef4e14260" dependencies = [ "bstr", - "byteyarn", "gix-glob", "gix-path", "gix-quote", "gix-trace", + "kstring", "smallvec", "thiserror", "unicode-bom", @@ -2025,36 +2482,39 @@ dependencies = [ [[package]] name = "gix-bitmap" -version = "0.2.7" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ccab4bc576844ddb51b78d81b4a42d73e6229660fa614dfc3d3999c874d1959" +checksum = "78b6cd0f246180034ddafac9b00a112f19178135b21eb031b3f79355891f7325" dependencies = [ "thiserror", ] [[package]] name = "gix-chunk" -version = "0.4.4" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b42ea64420f7994000130328f3c7a2038f639120518870436d31b8bde704493" +checksum = "003ec6deacf68076a0c157271a127e0bb2c031c1a41f7168cbe5d248d9b85c78" dependencies = [ "thiserror", ] [[package]] name = "gix-command" -version = "0.2.10" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c576cfbf577f72c097b5f88aedea502cd62952bdc1fb3adcab4531d5525a4c7" +checksum = "c82b5e9494e61983e61049bbd15fe0fa6b70672dd236362bdb5b2b50fc428f10" dependencies = [ "bstr", + "gix-path", + "gix-trace", + "shell-words", ] [[package]] name = "gix-commitgraph" -version = "0.21.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e75a975ee22cf0a002bfe9b5d5cb3d2a88e263a8a178cd7509133cff10f4df8a" +checksum = "82dbd7fb959862e3df2583331f0ad032ac93533e8a52f1b0694bc517f5d292bc" dependencies = [ "bstr", "gix-chunk", @@ -2066,9 +2526,9 @@ dependencies = [ [[package]] name = "gix-config" -version = "0.30.0" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c171514b40487d3f677ae37efc0f45ac980e3169f23c27eb30a70b47fdf88ab5" +checksum = "e62bf2073b6ce3921ffa6d8326f645f30eec5fc4a8e8a4bc0fcb721a2f3f69dc" dependencies = [ "bstr", "gix-config-value", @@ -2087,9 +2547,9 @@ dependencies = [ [[package]] name = "gix-config-value" -version = "0.14.0" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea7505b97f4d8e7933e29735a568ba2f86d8de466669d9f0e8321384f9972f47" +checksum = "5b8a1e7bfb37a46ed0b8468db37a6d8a0a61d56bdbe4603ae492cb322e5f3958" dependencies = [ "bitflags 2.4.0", "bstr", @@ -2100,9 +2560,9 @@ dependencies = [ [[package]] name = "gix-credentials" -version = "0.20.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46900b884cc5af6a6c141ee741607c0c651a4e1d33614b8d888a1ba81cc0bc8a" +checksum = "206ede3fe433abba3c8b0174179d5bbac65ae3f0d9187e2ea96c0494db6a139f" dependencies = [ "bstr", "gix-command", @@ -2110,15 +2570,16 @@ dependencies = [ "gix-path", "gix-prompt", "gix-sec", + "gix-trace", "gix-url", "thiserror", ] [[package]] name = "gix-date" -version = "0.8.0" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7df669639582dc7c02737642f76890b03b5544e141caba68a7d6b4eb551e0d" +checksum = "fb7f3dfb72bebe3449b5e642be64e3c6ccbe9821c8b8f19f487cf5bfbbf4067e" dependencies = [ "bstr", "itoa", @@ -2128,24 +2589,33 @@ dependencies = [ [[package]] name = "gix-diff" -version = "0.36.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "788ddb152c388206e81f36bcbb574e7ed7827c27d8fa62227b34edc333d8928c" +checksum = "cbdcb5e49c4b9729dd1c361040ae5c3cd7c497b2260b18c954f62db3a63e98cf" dependencies = [ + "bstr", + "gix-command", + "gix-filter", + "gix-fs", "gix-hash", "gix-object", + "gix-path", + "gix-tempfile", + "gix-trace", + "gix-worktree", "imara-diff", "thiserror", ] [[package]] name = "gix-discover" -version = "0.25.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69507643d75a0ea9a402fcf73ced517d2b95cc95385904ac09d03e0b952fde33" +checksum = "b4669218f3ec0cbbf8f16857b32200890f8ca585f36f5817242e4115fe4551af" dependencies = [ "bstr", "dunce", + "gix-fs", "gix-hash", "gix-path", "gix-ref", @@ -2155,9 +2625,9 @@ dependencies = [ [[package]] name = "gix-features" -version = "0.35.0" +version = "0.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b9ff423ae4983f762659040d13dd7a5defbd54b6a04ac3cc7347741cec828cd" +checksum = "184f7f7d4e45db0e2a362aeaf12c06c5e84817d0ef91d08e8e90170dad9f0b07" dependencies = [ "bytes", "bytesize", @@ -2166,6 +2636,7 @@ dependencies = [ "flate2", "gix-hash", "gix-trace", + "gix-utils", "jwalk", "libc", "once_cell", @@ -2178,9 +2649,9 @@ dependencies = [ [[package]] name = "gix-filter" -version = "0.5.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1be40d28cd41445bb6cd52c4d847d915900e5466f7433eaee6a9e0a3d1d88b08" +checksum = "9240862840fb740d209422937195e129e4ed3da49af212383260134bea8f6c1a" dependencies = [ "bstr", "encoding_rs", @@ -2192,24 +2663,26 @@ dependencies = [ "gix-path", "gix-quote", "gix-trace", + "gix-utils", "smallvec", "thiserror", ] [[package]] name = "gix-fs" -version = "0.7.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09815faba62fe9b32d918b75a554686c98e43f7d48c43a80df58eb718e5c6635" +checksum = "4436e883d5769f9fb18677b8712b49228357815f9e4104174a6fc2d8461a437b" dependencies = [ "gix-features", + "gix-utils", ] [[package]] name = "gix-glob" -version = "0.13.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d76e85f11251dcf751d2c5e918a14f562db5be6f727fd24775245653e9b19d" +checksum = "4965a1d06d0ab84a29d4a67697a97352ab14ae1da821084e5afb1fd6d8191ca0" dependencies = [ "bitflags 2.4.0", "bstr", @@ -2219,9 +2692,9 @@ dependencies = [ [[package]] name = "gix-hash" -version = "0.13.1" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1884c7b41ea0875217c1be9ce91322f90bde433e91d374d0e1276073a51ccc60" +checksum = "b0ed89cdc1dce26685c80271c4287077901de3c3dd90234d5fa47c22b2268653" dependencies = [ "faster-hex", "thiserror", @@ -2229,32 +2702,33 @@ dependencies = [ [[package]] name = "gix-hashtable" -version = "0.4.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "409268480841ad008e81c17ca5a293393fbf9f2b6c2f85b8ab9de1f0c5176a16" +checksum = "ebe47d8c0887f82355e2e9e16b6cecaa4d5e5346a7a474ca78ff94de1db35a5b" dependencies = [ "gix-hash", - "hashbrown 0.14.1", + "hashbrown 0.14.3", "parking_lot 0.12.1", ] [[package]] name = "gix-ignore" -version = "0.8.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048f443a1f6b02da4205c34d2e287e3fd45d75e8e2f06cfb216630ea9bff5e3" +checksum = "1f7069aaca4a05784c4cb44e392f0eaf627c6e57e05d3100c0e2386a37a682f0" dependencies = [ "bstr", "gix-glob", "gix-path", + "gix-trace", "unicode-bom", ] [[package]] name = "gix-index" -version = "0.25.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f54d63a9d13c13088f41f5a3accbec284e492ac8f4f707fcc307c139622e17b7" +checksum = "1d7152181ba8f0a3addc5075dd612cea31fc3e252b29c8be8c45f4892bf87426" dependencies = [ "bitflags 2.4.0", "bstr", @@ -2268,16 +2742,18 @@ dependencies = [ "gix-object", "gix-traverse", "itoa", + "libc", "memmap2", + "rustix", "smallvec", "thiserror", ] [[package]] name = "gix-lock" -version = "10.0.0" +version = "13.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47fc96fa8b6b6d33555021907c81eb3b27635daecf6e630630bdad44f8feaa95" +checksum = "886490a07b1d6433aa91262a99d430a91cc8b9a1f758ac1282e132f1098a9342" dependencies = [ "gix-tempfile", "gix-utils", @@ -2286,20 +2762,20 @@ dependencies = [ [[package]] name = "gix-macros" -version = "0.1.0" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d8acb5ee668d55f0f2d19a320a3f9ef67a6999ad483e11135abcc2464ed18b6" +checksum = "d75e7ab728059f595f6ddc1ad8771b8d6a231971ae493d9d5948ecad366ee8bb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.43", ] [[package]] name = "gix-mailmap" -version = "0.19.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40f00fa96e29e066ef208f5d13e0f5f95fa70c3ae4bd4f0234272ed4d708a7db" +checksum = "c8755c637aeeee7205fb605b4cfe5f8ff0ff48ad3d19b3ac98de7d0422538575" dependencies = [ "bstr", "gix-actor", @@ -2309,9 +2785,9 @@ dependencies = [ [[package]] name = "gix-negotiate" -version = "0.8.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f1697bf9911c6d1b8d709b9e6ef718cb5ea5821a1b7991520125a8134448004" +checksum = "a163adb84149e522e991cbe27250a6e01de56f98cd05b174614ce3f8a4e8b140" dependencies = [ "bitflags 2.4.0", "gix-commitgraph", @@ -2325,9 +2801,9 @@ dependencies = [ [[package]] name = "gix-object" -version = "0.37.0" +version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7e19616c67967374137bae83e950e9b518a9ea8a605069bd6716ada357fd6f" +checksum = "693ce9d30741506cb082ef2d8b797415b48e032cce0ab23eff894c19a7e4777b" dependencies = [ "bstr", "btoi", @@ -2344,13 +2820,14 @@ dependencies = [ [[package]] name = "gix-odb" -version = "0.53.0" +version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d6a392c6ba3a2f133cdc63120e9bc7aec81eef763db372c817de31febfe64bf" +checksum = "8ba2fa9e81f2461b78b4d81a807867667326c84cdab48e0aed7b73a593aa1be4" dependencies = [ "arc-swap", "gix-date", "gix-features", + "gix-fs", "gix-hash", "gix-object", "gix-pack", @@ -2363,9 +2840,9 @@ dependencies = [ [[package]] name = "gix-pack" -version = "0.43.0" +version = "0.47.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7536203a45b31e1bc5694bbf90ba8da1b736c77040dd6a520db369f371eb1ab3" +checksum = "8da5f3e78c96b76c4e6fe5e8e06b76221e4a0ee9a255aa935ed1fdf68988dfd8" dependencies = [ "clru", "gix-chunk", @@ -2384,20 +2861,21 @@ dependencies = [ [[package]] name = "gix-packetline-blocking" -version = "0.16.6" +version = "0.17.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d8395f7501c84d6a1fe902035fdfd8cd86d89e2dd6be0200ec1a72fd3c92d39" +checksum = "ca8ef6dd3ea50e26f3bf572e90c034d033c804d340cd1eb386392f184a9ba2f7" dependencies = [ "bstr", "faster-hex", + "gix-trace", "thiserror", ] [[package]] name = "gix-path" -version = "0.10.0" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a1d370115171e3ae03c5c6d4f7d096f2981a40ddccb98dfd704c773530ba73b" +checksum = "97e9ad649bf5e109562d6acba657ca428661ec08e77eaf3a755d8fa55485be9c" dependencies = [ "bstr", "gix-trace", @@ -2408,9 +2886,9 @@ dependencies = [ [[package]] name = "gix-pathspec" -version = "0.3.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3e26c9b47c51be73f98d38c84494bd5fb99334c5d6fda14ef5d036d50a9e5fd" +checksum = "9cbd49750edb26b0a691e5246fc635fa554d344da825cd20fa9ee0da9c1b761f" dependencies = [ "bitflags 2.4.0", "bstr", @@ -2423,9 +2901,9 @@ dependencies = [ [[package]] name = "gix-prompt" -version = "0.7.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c9a913769516f5e9d937afac206fb76428e3d7238e538845842887fda584678" +checksum = "02bd89d058258e53e0fd6c57f13ee16c5673a83066a68e11f88626fc8cfda5f6" dependencies = [ "gix-command", "gix-config-value", @@ -2436,9 +2914,9 @@ dependencies = [ [[package]] name = "gix-quote" -version = "0.4.7" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "475c86a97dd0127ba4465fbb239abac9ea10e68301470c9791a6dd5351cdc905" +checksum = "9f7dc10303d73a960d10fb82f81188b036ac3e6b11b5795b20b1a60b51d1321f" dependencies = [ "bstr", "btoi", @@ -2447,9 +2925,9 @@ dependencies = [ [[package]] name = "gix-ref" -version = "0.37.0" +version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e6b749660b613641769edc1954132eb8071a13c32224891686091bef078de4" +checksum = "5818958994ad7879fa566f5441ebcc48f0926aa027b28948e6fbf6578894dc31" dependencies = [ "gix-actor", "gix-date", @@ -2460,6 +2938,7 @@ dependencies = [ "gix-object", "gix-path", "gix-tempfile", + "gix-utils", "gix-validate", "memmap2", "thiserror", @@ -2468,9 +2947,9 @@ dependencies = [ [[package]] name = "gix-refspec" -version = "0.18.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0895cb7b1e70f3c3bd4550c329e9f5caf2975f97fcd4238e05754e72208ef61e" +checksum = "613aa4d93034c5791d13bdc635e530f4ddab1412ddfb4a8215f76213177b61c7" dependencies = [ "bstr", "gix-hash", @@ -2482,9 +2961,9 @@ dependencies = [ [[package]] name = "gix-revision" -version = "0.22.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8c4b15cf2ab7a35f5bcb3ef146187c8d36df0177e171ca061913cbaaa890e89" +checksum = "288f6549d7666db74dc3f169a9a333694fc28ecd2f5aa7b2c979c89eb556751a" dependencies = [ "bstr", "gix-date", @@ -2498,9 +2977,9 @@ dependencies = [ [[package]] name = "gix-revwalk" -version = "0.8.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9870c6b1032f2084567710c3b2106ac603377f8d25766b8a6b7c33e6e3ca279" +checksum = "5b9b4d91dfc5c14fee61a28c65113ded720403b65a0f46169c0460f731a5d03c" dependencies = [ "gix-commitgraph", "gix-date", @@ -2513,39 +2992,40 @@ dependencies = [ [[package]] name = "gix-sec" -version = "0.10.0" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92b9542ac025a8c02ed5d17b3fc031a111a384e859d0be3532ec4d58c40a0f28" +checksum = "f8d9bf462feaf05f2121cba7399dbc6c34d88a9cad58fc1e95027791d6a3c6d2" dependencies = [ "bitflags 2.4.0", "gix-path", "libc", - "windows", + "windows-sys 0.52.0", ] [[package]] name = "gix-status" -version = "0.1.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "082801c42ba707f2407b5cce3d99b89cfa84f3794962946dc94cfdc00ae522fa" +checksum = "324d6b9ad77d9e1b73611ce274f4fc1145bf29bc893e18c9e378981d0dc4ae80" dependencies = [ "bstr", "filetime", "gix-features", + "gix-filter", "gix-fs", "gix-hash", "gix-index", "gix-object", "gix-path", - "gix-pathspec", + "gix-worktree", "thiserror", ] [[package]] name = "gix-submodule" -version = "0.4.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0150e82e9282d3f2ab2dd57a22f9f6c3447b9d9856e5321ac92d38e3e0e2b7" +checksum = "73182f6c1f5ed1ed94ba16581ac62593d5e29cd1c028b2af618f836283b8f8d4" dependencies = [ "bstr", "gix-config", @@ -2558,10 +3038,11 @@ dependencies = [ [[package]] name = "gix-tempfile" -version = "10.0.0" +version = "13.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ae0978f3e11dc57290ee75ac2477c815bca1ce2fa7ed5dc5f16db067410ac4d" +checksum = "439f4da9657aec7434cde3c2510dcdb0a35f2031233ff67ae986269c788966d7" dependencies = [ + "dashmap", "gix-fs", "libc", "once_cell", @@ -2573,15 +3054,15 @@ dependencies = [ [[package]] name = "gix-trace" -version = "0.1.3" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b6d623a1152c3facb79067d6e2ecdae48130030cf27d6eb21109f13bd7b836" +checksum = "02b202d766a7fefc596e2cc6a89cda8ad8ad733aed82da635ac120691112a9b1" [[package]] name = "gix-traverse" -version = "0.33.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ef04ab3643acba289b5cedd25d6f53c0430770b1d689d1d654511e6fb81ba0" +checksum = "bfc30c5b5e4e838683b59e1b0574ce6bc1c35916df9709aaab32bb7751daf08b" dependencies = [ "gix-commitgraph", "gix-date", @@ -2595,9 +3076,9 @@ dependencies = [ [[package]] name = "gix-url" -version = "0.24.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6125ecf46e8c68bf7202da6cad239831daebf0247ffbab30210d72f3856e420f" +checksum = "26f1981ecc700f4fd73ae62b9ca2da7c8816c8fd267f0185e3f8c21e967984ac" dependencies = [ "bstr", "gix-features", @@ -2609,18 +3090,19 @@ dependencies = [ [[package]] name = "gix-utils" -version = "0.1.5" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b85d89dc728613e26e0ed952a19583744e7f5240fcd4aa30d6c824ffd8b52f0f" +checksum = "56e839f3d0798b296411263da6bee780a176ef8008a5dfc31287f7eda9266ab8" dependencies = [ "fastrand", + "unicode-normalization", ] [[package]] name = "gix-validate" -version = "0.8.0" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e05cab2b03a45b866156e052aa38619f4ece4adcb2f79978bfc249bc3b21b8c5" +checksum = "ac7cc36f496bd5d96cdca0f9289bb684480725d40db60f48194aa7723b883854" dependencies = [ "bstr", "thiserror", @@ -2628,9 +3110,9 @@ dependencies = [ [[package]] name = "gix-worktree" -version = "0.26.0" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f5e32972801bd82d56609e6fc84efc358fa1f11f25c5e83b7807ee2280f14fe" +checksum = "ca36bb3dc54038c66507dc75c4d8edbee2d6d5cc45227b4eb508ad13dd60a006" dependencies = [ "bstr", "gix-attributes", @@ -2646,9 +3128,9 @@ dependencies = [ [[package]] name = "gix-worktree-state" -version = "0.3.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3aeb06960f2c5ac9e4cdb6b38eb3c2b99d5e525e68285fef21ed17dfbd597ad" +checksum = "8ae178614b70bdb0c7f6f21b8c9fb711ab78bd7e8e1866f565fcf28876747f1d" dependencies = [ "bstr", "gix-features", @@ -2666,9 +3148,9 @@ dependencies = [ [[package]] name = "gix-worktree-stream" -version = "0.5.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c89fe93a12e45cc3ad6ba429a7dd7506b03d7d406374a65ad9998b5cb2627569" +checksum = "7f5330e8c071ac47d27ad8e666a58bdf95ff47a8f7fc8ccc2d1dc95fd381d57d" dependencies = [ "gix-attributes", "gix-features", @@ -2703,9 +3185,9 @@ dependencies = [ [[package]] name = "good_lp" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "869f19637130a4e8e1c3f3f83df4a00a169c1d3a77a2b2ff41736b14497c4027" +checksum = "fa124423ded10046a849fa0ae9747c541895557f1af177e0890b09879e7e9e7d" dependencies = [ "fnv", "minilp", @@ -2745,16 +3227,16 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.7", ] [[package]] name = "hashbrown" -version = "0.14.1" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.7", "allocator-api2", "serde", ] @@ -2874,6 +3356,20 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http", + "hyper", + "rustls", + "tokio", + "tokio-rustls", +] + [[package]] name = "hyper-tls" version = "0.5.0" @@ -2901,9 +3397,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -2932,7 +3428,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e98c1d0ad70fc91b8b9654b1f33db55e59579d3b3de2bffdced0fdb810570cb8" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.7", "hashbrown 0.12.3", ] @@ -2985,12 +3481,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.2" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" +checksum = "824b2ae422412366ba479e8111fd301f7b5faece8149317bb81925979a53f520" dependencies = [ "equivalent", - "hashbrown 0.14.1", + "hashbrown 0.14.3", "serde", ] @@ -3108,6 +3604,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.9" @@ -3161,6 +3666,15 @@ dependencies = [ "winapi-build", ] +[[package]] +name = "kstring" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3066350882a1cd6d950d055997f379ac37fd39f81cd4d8ed186032eb3c5747" +dependencies = [ + "static_assertions", +] + [[package]] name = "lalrpop" version = "0.20.0" @@ -3199,7 +3713,7 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" dependencies = [ - "spin", + "spin 0.5.2", ] [[package]] @@ -3210,9 +3724,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.148" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libmimalloc-sys" @@ -3226,9 +3740,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.8" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3852614a3bd9ca9804678ba6be5e3b8ce76dfc902cae004e3e0c44051b6e88db" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "lock_api" @@ -3281,9 +3795,9 @@ checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "memmap2" -version = "0.7.1" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f49388d20533534cd19360ad3d6a7dadc885944aa802ba3995040c5ec11288c6" +checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322" dependencies = [ "libc", ] @@ -3636,7 +4150,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.43", ] [[package]] @@ -3698,6 +4212,7 @@ dependencies = [ "bitvec", "byte-slice-cast", "impl-trait-for-tuples", + "parity-scale-codec-derive", "serde", ] @@ -3793,9 +4308,9 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "petgraph" @@ -3804,7 +4319,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap 2.0.2", + "indexmap 2.2.2", ] [[package]] @@ -3914,9 +4429,9 @@ dependencies = [ [[package]] name = "prodash" -version = "26.2.2" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "794b5bf8e2d19b53dcdcec3e4bba628e20f5b6062503ba89281fa7037dd7bbcf" +checksum = "744a264d26b88a6a7e37cbad97953fa233b94d585236310bcbc88474b4092d79" dependencies = [ "bytesize", "human_format", @@ -4004,28 +4519,28 @@ dependencies = [ ] [[package]] -name = "redox_syscall" -version = "0.2.16" +name = "redb" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +checksum = "72623e6275cd430215b741f41ebda34db93a13ebde253f908b70871c46afc5ba" dependencies = [ - "bitflags 1.3.2", + "libc", ] [[package]] name = "redox_syscall" -version = "0.3.5" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ "bitflags 1.3.2", ] [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ "bitflags 1.3.2", ] @@ -4113,6 +4628,7 @@ dependencies = [ "http", "http-body", "hyper", + "hyper-rustls", "hyper-tls", "ipnet", "js-sys", @@ -4122,12 +4638,16 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", + "rustls", + "rustls-native-certs", + "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", "system-configuration", "tokio", "tokio-native-tls", + "tokio-rustls", "tokio-util", "tower-service", "url", @@ -4148,6 +4668,20 @@ dependencies = [ "subtle", ] +[[package]] +name = "ring" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +dependencies = [ + "cc", + "getrandom", + "libc", + "spin 0.9.8", + "untrusted", + "windows-sys 0.48.0", +] + [[package]] name = "rustc-demangle" version = "0.1.23" @@ -4171,15 +4705,58 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.21" +version = "0.38.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" dependencies = [ "bitflags 2.4.0", "errno", "libc", "linux-raw-sys", - "windows-sys 0.48.0", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.21.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +dependencies = [ + "log", + "ring", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-native-certs" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", ] [[package]] @@ -4234,21 +4811,23 @@ dependencies = [ [[package]] name = "scarb" -version = "2.3.0" -source = "git+https://github.com/software-mansion/scarb#7eb2819a2a2ad5ce8d1c3f760e3274a2ea576e60" +version = "2.5.3" +source = "git+https://github.com/software-mansion/scarb#5189ae09e2be80e5ed70c0f927b0bcd297454b5d" dependencies = [ "anyhow", "async-trait", - "cairo-lang-compiler", - "cairo-lang-defs", - "cairo-lang-filesystem", + "cairo-lang-compiler 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-defs 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-diagnostics 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-filesystem 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", "cairo-lang-formatter", - "cairo-lang-semantic", - "cairo-lang-sierra", - "cairo-lang-sierra-to-casm", - "cairo-lang-starknet", - "cairo-lang-test-plugin", - "cairo-lang-utils", + "cairo-lang-semantic 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-sierra 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-sierra-to-casm 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-starknet 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-starknet-classes", + "cairo-lang-test-plugin 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", + "cairo-lang-utils 2.5.3 (git+https://github.com/starkware-libs/cairo?rev=7bf91178ad4a775943da53f1dab94068e5d70e31)", "camino", "clap", "clap-verbosity-flag", @@ -4259,16 +4838,18 @@ dependencies = [ "directories", "dunce", "fs4", + "fs_extra", "futures", "gix", "glob", "ignore", "include_dir", "indoc", - "itertools 0.11.0", + "itertools 0.12.1", "once_cell", "pathdiff", "petgraph", + "redb", "reqwest", "scarb-build-metadata", "scarb-metadata", @@ -4285,16 +4866,16 @@ dependencies = [ "tar", "thiserror", "tokio", - "toml 0.8.2", - "toml_edit 0.20.2", + "toml 0.8.10", + "toml_edit 0.21.1", "tracing", - "tracing-log", + "tracing-log 0.2.0", "tracing-subscriber", "typed-builder", "url", "walkdir", "which", - "windows-sys 0.48.0", + "windows-sys 0.52.0", "xxhash-rust", "zip", "zstd", @@ -4302,16 +4883,16 @@ dependencies = [ [[package]] name = "scarb-build-metadata" -version = "2.3.0" -source = "git+https://github.com/software-mansion/scarb#7eb2819a2a2ad5ce8d1c3f760e3274a2ea576e60" +version = "2.5.3" +source = "git+https://github.com/software-mansion/scarb#5189ae09e2be80e5ed70c0f927b0bcd297454b5d" dependencies = [ "cargo_metadata", ] [[package]] name = "scarb-metadata" -version = "1.8.0" -source = "git+https://github.com/software-mansion/scarb#7eb2819a2a2ad5ce8d1c3f760e3274a2ea576e60" +version = "1.11.1" +source = "git+https://github.com/software-mansion/scarb#5189ae09e2be80e5ed70c0f927b0bcd297454b5d" dependencies = [ "camino", "derive_builder", @@ -4323,8 +4904,8 @@ dependencies = [ [[package]] name = "scarb-ui" -version = "0.1.0" -source = "git+https://github.com/software-mansion/scarb#7eb2819a2a2ad5ce8d1c3f760e3274a2ea576e60" +version = "0.1.3" +source = "git+https://github.com/software-mansion/scarb#5189ae09e2be80e5ed70c0f927b0bcd297454b5d" dependencies = [ "anyhow", "camino", @@ -4376,6 +4957,16 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "security-framework" version = "2.9.2" @@ -4410,9 +5001,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.188" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" dependencies = [ "serde_derive", ] @@ -4439,13 +5030,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.43", ] [[package]] @@ -4478,14 +5069,14 @@ checksum = "3081f5ffbb02284dda55132aa26daecedd7372a42417bbbab6f14ab7d6bb9145" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.43", ] [[package]] name = "serde_spanned" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" dependencies = [ "serde", ] @@ -4524,7 +5115,7 @@ checksum = "91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.43", ] [[package]] @@ -4563,6 +5154,12 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shell-words" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" + [[package]] name = "signal-hook" version = "0.3.17" @@ -4638,6 +5235,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + [[package]] name = "sprs" version = "0.7.1" @@ -4658,10 +5261,10 @@ dependencies = [ "ark-ff", "ark-std 0.3.0", "assert_cmd", - "cairo-felt", + "cairo-felt 0.8.7", "cairo-lang-runner", - "cairo-lang-sierra", - "cairo-lang-test-plugin", + "cairo-lang-sierra 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-lang-test-plugin 2.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "cairo-lang-test-runner", "camino", "clap", @@ -4690,9 +5293,9 @@ dependencies = [ [[package]] name = "starknet-crypto" -version = "0.5.2" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3f2175b0b3fc24ff2ec6dc07f5a720498994effca7e78b11a6e1c1bd02cad52" +checksum = "33c03f5ac70f9b067f48db7d2d70bdf18ee0f731e8192b6cfa679136becfcdb0" dependencies = [ "crypto-bigint", "hex", @@ -4703,7 +5306,7 @@ dependencies = [ "rfc6979", "sha2", "starknet-crypto-codegen", - "starknet-curve 0.3.0", + "starknet-curve", "starknet-ff", "zeroize", ] @@ -4714,18 +5317,9 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af6527b845423542c8a16e060ea1bc43f67229848e7cd4c4d80be994a84220ce" dependencies = [ - "starknet-curve 0.4.0", - "starknet-ff", - "syn 2.0.37", -] - -[[package]] -name = "starknet-curve" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "252610baff59e4c4332ce3569f7469c5d3f9b415a2240d698fb238b2b4fc0942" -dependencies = [ + "starknet-curve", "starknet-ff", + "syn 2.0.43", ] [[package]] @@ -4749,6 +5343,12 @@ dependencies = [ "hex", ] +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "string_cache" version = "0.8.7" @@ -4787,9 +5387,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.37" +version = "2.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" +checksum = "ee659fb5f3d355364e1f3e5bc10fb82068efbf824a1e9d1c9504244a6469ad53" dependencies = [ "proc-macro2", "quote", @@ -4836,15 +5436,14 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.8.1" +version = "3.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67" dependencies = [ "cfg-if 1.0.0", "fastrand", - "redox_syscall 0.4.1", "rustix", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -4875,22 +5474,22 @@ checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" [[package]] name = "thiserror" -version = "1.0.49" +version = "1.0.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" +checksum = "6e3de26b0965292219b4287ff031fcba86837900fe9cd2b34ea8ad893c0953d2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.49" +version = "1.0.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" +checksum = "268026685b2be38d7103e9e507c938a1fcb3d7e6eb15e87870b617bf37b6d581" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.43", ] [[package]] @@ -5004,7 +5603,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.43", ] [[package]] @@ -5017,6 +5616,16 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", +] + [[package]] name = "tokio-util" version = "0.7.10" @@ -5042,44 +5651,43 @@ dependencies = [ [[package]] name = "toml" -version = "0.7.8" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" +checksum = "9a9aad4a3066010876e8dcf5a8a06e70a558751117a145c6ce2b82c2e2054290" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.19.15", + "toml_edit 0.22.4", ] [[package]] -name = "toml" -version = "0.8.2" +name = "toml_datetime" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" dependencies = [ "serde", - "serde_spanned", - "toml_datetime", - "toml_edit 0.20.2", ] [[package]] -name = "toml_datetime" -version = "0.6.3" +name = "toml_edit" +version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "serde", + "indexmap 2.2.2", + "toml_datetime", + "winnow", ] [[package]] name = "toml_edit" -version = "0.19.15" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ - "indexmap 2.0.2", + "indexmap 2.2.2", "serde", "serde_spanned", "toml_datetime", @@ -5088,11 +5696,11 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.20.2" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +checksum = "0c9ffdf896f8daaabf9b66ba8e77ea1ed5ed0f72821b398aba62352e95062951" dependencies = [ - "indexmap 2.0.2", + "indexmap 2.2.2", "serde", "serde_spanned", "toml_datetime", @@ -5124,7 +5732,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.43", ] [[package]] @@ -5148,6 +5756,17 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + [[package]] name = "tracing-subscriber" version = "0.3.17" @@ -5163,7 +5782,7 @@ dependencies = [ "thread_local", "tracing", "tracing-core", - "tracing-log", + "tracing-log 0.1.4", ] [[package]] @@ -5174,22 +5793,22 @@ checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "typed-builder" -version = "0.16.2" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34085c17941e36627a879208083e25d357243812c30e7d7387c3b954f30ade16" +checksum = "444d8748011b93cb168770e8092458cb0f8854f931ff82fdf6ddfbd72a9c933e" dependencies = [ "typed-builder-macro", ] [[package]] name = "typed-builder-macro" -version = "0.16.2" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f03ca4cb38206e2bef0700092660bb74d696f808514dae47fa1467cbfe26e96e" +checksum = "563b3b88238ec95680aef36bdece66896eaa7ce3c0f1b4f39d38fb2435261352" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.43", ] [[package]] @@ -5261,11 +5880,17 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", "idna", @@ -5343,7 +5968,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.43", "wasm-bindgen-shared", ] @@ -5377,7 +6002,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.43", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -5413,14 +6038,15 @@ dependencies = [ [[package]] name = "which" -version = "4.4.2" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +checksum = "9bf3ea8596f3a0dd5980b46430f2058dfe2c36a27ccfbb1845d6fbfcd9ba6e14" dependencies = [ "either", "home", "once_cell", "rustix", + "windows-sys 0.48.0", ] [[package]] @@ -5466,15 +6092,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" -dependencies = [ - "windows-targets 0.48.5", -] - [[package]] name = "windows-sys" version = "0.45.0" @@ -5493,6 +6110,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + [[package]] name = "windows-targets" version = "0.42.2" @@ -5523,6 +6149,21 @@ dependencies = [ "windows_x86_64_msvc 0.48.5", ] +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -5535,6 +6176,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -5547,6 +6194,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -5559,6 +6212,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -5571,6 +6230,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -5583,6 +6248,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -5595,6 +6266,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -5607,11 +6284,17 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + [[package]] name = "winnow" -version = "0.5.15" +version = "0.5.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" +checksum = "5389a154b01683d28c77f8f68f49dea75f0a4da32557a58f68ee51ebba472d29" dependencies = [ "memchr", ] @@ -5675,6 +6358,26 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9828b178da53440fa9c766a3d2f73f7cf5d0ac1fe3980c1e5018d899fd19e07b" +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.43", +] + [[package]] name = "zeroize" version = "1.6.0" @@ -5692,7 +6395,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.43", ] [[package]] @@ -5709,20 +6412,19 @@ dependencies = [ [[package]] name = "zstd" -version = "0.12.4" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c" +checksum = "bffb3309596d527cfcba7dfc6ed6052f1d39dfbd7c867aa2e865e4a449c10110" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "6.0.6" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee98ffd0b48ee95e6c5168188e44a54550b1564d9d530ee21d5f0eaed1069581" +checksum = "43747c7422e2924c11144d5229878b98180ef8b06cca4ab5af37afc8a8d8ea3e" dependencies = [ - "libc", "zstd-sys", ] diff --git a/Cargo.toml b/Cargo.toml index e690a3cc9..15589458e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,12 +24,12 @@ glob = "0.3.0" cairo-felt = "0.8.2" # Cairo runner dependencies -cairo-lang-test-runner = {git = "https://github.com/starkware-libs/cairo", rev = "bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f"} -cairo-lang-test-plugin = {git = "https://github.com/starkware-libs/cairo", rev = "bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f"} -cairo-lang-runner = {git = "https://github.com/starkware-libs/cairo", rev = "bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f"} -cairo-lang-sierra = {git = "https://github.com/starkware-libs/cairo", rev = "bf91adecc5a1cb2ced041ba383d7b7c38dd2fa7f"} -scarb = { git = "https://github.com/software-mansion/scarb", version = "2.3.0" } -scarb-ui = { git = "https://github.com/software-mansion/scarb", version = "0.1.0" } +cairo-lang-test-runner = "2.5.3" +cairo-lang-test-plugin = "2.5.3" +cairo-lang-runner = "2.5.3" +cairo-lang-sierra = "2.5.3" +scarb = { git = "https://github.com/software-mansion/scarb", version = "2.5.3" } +scarb-ui = { git = "https://github.com/software-mansion/scarb", version = "0.1.3" } anyhow = "1.0.66" ark-ff = "0.4.0-alpha.7" diff --git a/corelib/Scarb.lock b/corelib/Scarb.lock index 7a36cbba5..0bd6895c9 100644 --- a/corelib/Scarb.lock +++ b/corelib/Scarb.lock @@ -3,4 +3,4 @@ version = 1 [[package]] name = "core" -version = "2.3.0" +version = "2.4.1" diff --git a/corelib/Scarb.toml b/corelib/Scarb.toml index e86636584..3982c2ed8 100644 --- a/corelib/Scarb.toml +++ b/corelib/Scarb.toml @@ -1,6 +1,7 @@ [package] name = "core" -version = "2.3.0" +version = "2.5.3" +edition = "2023_11" # 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/cairo_project.toml b/corelib/cairo_project.toml index db46c53c2..40985b4d1 100644 --- a/corelib/cairo_project.toml +++ b/corelib/cairo_project.toml @@ -1,2 +1,8 @@ [crate_roots] core = "src" + +[config.global] +edition = "2023_11" + +[config.global.experimental_features] +negative_impls = true diff --git a/corelib/src/array.cairo b/corelib/src/array.cairo index a37227fa5..30164a447 100644 --- a/corelib/src/array.cairo +++ b/corelib/src/array.cairo @@ -1,12 +1,13 @@ -use traits::IndexView; +use core::traits::IndexView; -use box::BoxTrait; -use gas::withdraw_gas; -use option::OptionTrait; -use serde::Serde; +use core::box::BoxTrait; +use core::gas::withdraw_gas; +use core::option::OptionTrait; +use core::serde::Serde; +use core::metaprogramming::TypeEqual; #[derive(Drop)] -extern type Array; +pub extern type Array; extern fn array_new() -> Array nopanic; extern fn array_append(ref arr: Array, value: T) nopanic; @@ -24,15 +25,24 @@ extern fn array_slice( extern fn array_len(arr: @Array) -> usize nopanic; #[generate_trait] -impl ArrayImpl of ArrayTrait { +pub impl ArrayImpl of ArrayTrait { #[inline(always)] fn new() -> Array { array_new() } #[inline(always)] - fn append(ref self: Array, value: T) { + fn append(ref self: Array, value: T) nopanic { array_append(ref self, value) } + fn append_span<+Clone, +Drop>(ref self: Array, mut span: Span) { + match span.pop_front() { + Option::Some(current) => { + self.append(current.clone()); + self.append_span(span); + }, + Option::None => {} + }; + } #[inline(always)] fn pop_front(ref self: Array) -> Option nopanic { match array_pop_front(ref self) { @@ -55,14 +65,21 @@ impl ArrayImpl of ArrayTrait { array_at(self, index).unbox() } #[inline(always)] + #[must_use] fn len(self: @Array) -> usize { array_len(self) } #[inline(always)] + #[must_use] fn is_empty(self: @Array) -> bool { - self.len() == 0_usize + let mut snapshot = self; + match array_snapshot_pop_front(ref snapshot) { + Option::Some(_) => false, + Option::None => true, + } } #[inline(always)] + #[must_use] fn span(self: @Array) -> Span { Span { snapshot: self } } @@ -114,14 +131,28 @@ fn deserialize_array_helper, +Drop>( } // Span. -struct Span { +pub struct Span { snapshot: @Array } impl SpanCopy of Copy>; impl SpanDrop of Drop>; -impl SpanSerde, +Drop> of Serde> { +impl SpanFelt252Serde of Serde> { + fn serialize(self: @Span, ref output: Array) { + (*self).len().serialize(ref output); + serialize_array_helper(*self, ref output) + } + + fn deserialize(ref serialized: Span) -> Option> { + let length: u32 = (*serialized.pop_front()?).try_into()?; + let res = serialized.slice(0, length); + serialized = serialized.slice(length, serialized.len() - length); + Option::Some(res) + } +} + +impl SpanSerde, +Drop, -TypeEqual> of Serde> { fn serialize(self: @Span, ref output: Array) { (*self).len().serialize(ref output); serialize_array_helper(*self, ref output) @@ -135,7 +166,7 @@ impl SpanSerde, +Drop> of Serde> { } #[generate_trait] -impl SpanImpl of SpanTrait { +pub impl SpanImpl of SpanTrait { #[inline(always)] fn pop_front(ref self: Span) -> Option<@T> { let mut snapshot = self.snapshot; @@ -169,16 +200,22 @@ impl SpanImpl of SpanTrait { Span { snapshot: array_slice(self.snapshot, start, length).expect('Index out of bounds') } } #[inline(always)] + #[must_use] fn len(self: Span) -> usize { array_len(self.snapshot) } #[inline(always)] + #[must_use] fn is_empty(self: Span) -> bool { - self.len() == 0_usize + let mut snapshot = self.snapshot; + match array_snapshot_pop_front(ref snapshot) { + Option::Some(_) => false, + Option::None => true, + } } } -impl SpanIndex of IndexView, usize, @T> { +pub impl SpanIndex of IndexView, usize, @T> { #[inline(always)] fn index(self: @Span, index: usize) -> @T { array_at(*self.snapshot, index).unbox() diff --git a/corelib/src/boolean.cairo b/corelib/src/boolean.cairo new file mode 100644 index 000000000..f51efba4d --- /dev/null +++ b/corelib/src/boolean.cairo @@ -0,0 +1,19 @@ +#[generate_trait] +pub impl BoolImpl> of BoolTrait { + /// Returns `Some(t)` if the `bool` is `true`, or `None` otherwise. + /// + /// # Examples + /// + /// ``` + /// assert(false.then_some(0) == Option::None); + /// assert(true.then_some(0) == Option::Some(0)); + /// ``` + #[inline(always)] + fn then_some(self: bool, t: T) -> Option nopanic { + if self { + Option::Some(t) + } else { + Option::None + } + } +} diff --git a/corelib/src/box.cairo b/corelib/src/box.cairo index 83210965b..706bdaa7d 100644 --- a/corelib/src/box.cairo +++ b/corelib/src/box.cairo @@ -1,20 +1,34 @@ #[derive(Copy, Drop)] -extern type Box; +pub extern type Box; // These functions are only exposed in the corelib through the trait below since calling them // directly with tuples panics due to auto unpacking of the tuple. // TODO(Gil): Expose in the core lib when the described behaviour is fixed. extern fn into_box(value: T) -> Box nopanic; extern fn unbox(box: Box) -> T nopanic; +extern fn box_forward_snapshot(value: @Box) -> Box<@T> nopanic; #[generate_trait] -impl BoxImpl of BoxTrait { +pub impl BoxImpl of BoxTrait { #[inline(always)] + #[must_use] fn new(value: T) -> Box nopanic { into_box(value) } #[inline(always)] + #[must_use] fn unbox(self: Box) -> T nopanic { unbox(self) } + #[must_use] + fn as_snapshot(self: @Box) -> Box<@T> nopanic { + box_forward_snapshot(self) + } +} + +impl BoxDebug> of core::fmt::Debug> { + fn fmt(self: @Box, ref f: core::fmt::Formatter) -> Result<(), core::fmt::Error> { + write!(f, "&")?; + TDebug::fmt(self.as_snapshot().unbox(), ref f) + } } diff --git a/corelib/src/byte_array.cairo b/corelib/src/byte_array.cairo index 869e7d6fd..ce6df4cfd 100644 --- a/corelib/src/byte_array.cairo +++ b/corelib/src/byte_array.cairo @@ -1,44 +1,44 @@ -use array::{ArrayTrait, SpanTrait}; -use bytes_31::{ +use core::array::{ArrayTrait, SpanTrait}; +use core::bytes_31::{ BYTES_IN_BYTES31, Bytes31Trait, one_shift_left_bytes_felt252, one_shift_left_bytes_u128, POW_2_128, POW_2_8, U128IntoBytes31, U8IntoBytes31 }; -use clone::Clone; -use cmp::min; -use integer::{u128_safe_divmod, U32TryIntoNonZero}; -use option::OptionTrait; -use traits::{Into, TryInto}; -use zeroable::NonZeroIntoImpl; - +use core::clone::Clone; +use core::cmp::min; +use core::integer::{u128_safe_divmod, U32TryIntoNonZero}; +use core::option::OptionTrait; +use core::traits::{Into, TryInto}; +use core::serde::Serde; +use core::zeroable::NonZeroIntoImpl; + +/// A magic constant for identifying serialization of ByteArrays. An array of felt252s with this +/// magic as one of the felt252s indicates that right after it you should expect a serialized +/// ByteArray. This is currently used mainly for prints and panics. +pub(crate) const BYTE_ARRAY_MAGIC: felt252 = + 0x46a6158a16a947e5916b2a2ca68501a45e93d7110e81aa2d6438b1c57c879a3; const BYTES_IN_U128: usize = 16; // TODO(yuval): change to `BYTES_IN_BYTES31 - 1` once consteval_int supports non-literals. const BYTES_IN_BYTES31_MINUS_ONE: usize = consteval_int!(31 - 1); // TODO(yuval): don't allow creation of invalid ByteArray? -#[derive(Drop, Clone, PartialEq)] -struct ByteArray { +#[derive(Drop, Clone, PartialEq, Serde, Default)] +pub struct ByteArray { // Full "words" of 31 bytes each. The first byte of each word in the byte array // is the most significant byte in the word. - data: Array, + pub(crate) data: Array, // This felt252 actually represents a bytes31, with < 31 bytes. // It is represented as a felt252 to improve performance of building the byte array. // The number of bytes in here is specified in `pending_word_len`. // The first byte is the most significant byte among the `pending_word_len` bytes in the word. - pending_word: felt252, + pub(crate) pending_word: felt252, // Should be in range [0, 30]. - pending_word_len: usize, + pub(crate) pending_word_len: usize, } -impl ByteArrayStringLiteral of string::StringLiteral; - -impl ByteArrayDefault of Default { - fn default() -> ByteArray { - ByteArray { data: Default::default(), pending_word: 0, pending_word_len: 0 } - } -} +pub(crate) impl ByteArrayStringLiteral of core::string::StringLiteral; #[generate_trait] -impl ByteArrayImpl of ByteArrayTrait { +pub impl ByteArrayImpl of ByteArrayTrait { // TODO(yuval): add a `new` function for initialization. // Appends a single word of `len` bytes to the end of the ByteArray. @@ -90,12 +90,7 @@ impl ByteArrayImpl of ByteArrayTrait { let mut other_data = other.data.span(); if self.pending_word_len == 0 { - loop { - match other_data.pop_front() { - Option::Some(current_word) => { self.data.append(*current_word); }, - Option::None => { break; } - }; - }; + self.data.append_span(other_data); self.pending_word = *other.pending_word; self.pending_word_len = *other.pending_word_len; return; @@ -172,6 +167,7 @@ impl ByteArrayImpl of ByteArrayTrait { self.pending_word_len = 0; } + #[must_use] fn len(self: @ByteArray) -> usize { self.data.len() * BYTES_IN_BYTES31.into() + (*self.pending_word_len).into() } @@ -359,7 +355,7 @@ impl ByteArrayAddEq of AddEq { } } -impl ByteArrayIndexView of IndexView { +pub(crate) impl ByteArrayIndexView of IndexView { fn index(self: @ByteArray, index: usize) -> u8 { self.at(index).expect('Index out of bounds') } diff --git a/corelib/src/bytes_31.cairo b/corelib/src/bytes_31.cairo index d4a913b26..a5763c051 100644 --- a/corelib/src/bytes_31.cairo +++ b/corelib/src/bytes_31.cairo @@ -1,21 +1,21 @@ -use traits::{Into, TryInto}; -use option::OptionTrait; -use integer::{u256_from_felt252, u128_safe_divmod, u128_to_felt252}; +use core::traits::{Into, TryInto}; +use core::option::OptionTrait; +use core::integer::{u128_safe_divmod, u128_to_felt252}; -const BYTES_IN_BYTES31: usize = 31; +pub(crate) const BYTES_IN_BYTES31: usize = 31; const BYTES_IN_U128: usize = 16; -const POW_2_128: felt252 = 0x100000000000000000000000000000000; -const POW_2_8: u128 = 0x100; +pub(crate) const POW_2_128: felt252 = 0x100000000000000000000000000000000; +pub(crate) const POW_2_8: u128 = 0x100; #[derive(Copy, Drop)] -extern type bytes31; +pub extern type bytes31; -extern fn bytes31_const() -> bytes31 nopanic; +pub(crate) extern fn bytes31_const() -> bytes31 nopanic; extern fn bytes31_try_from_felt252(value: felt252) -> Option implicits(RangeCheck) nopanic; extern fn bytes31_to_felt252(value: bytes31) -> felt252 nopanic; #[generate_trait] -impl Bytes31Impl of Bytes31Trait { +pub impl Bytes31Impl of Bytes31Trait { // Gets the byte at the given index (LSB's index is 0), assuming that // `index < BYTES_IN_BYTES31`. If the assumption is not met, the behavior is undefined. fn at(self: @bytes31, index: usize) -> u8 { @@ -29,60 +29,62 @@ impl Bytes31Impl of Bytes31Trait { } } -impl Bytes31IndexView of IndexView { +pub(crate) impl Bytes31IndexView of IndexView { fn index(self: @bytes31, index: usize) -> u8 { self.at(index) } } -impl Bytes31IntoFelt252 of Into { +impl Bytes31BitSize of core::num::traits::BitSize { + fn bits() -> usize { + 248 + } +} + +pub(crate) impl Bytes31IntoFelt252 of Into { fn into(self: bytes31) -> felt252 { bytes31_to_felt252(self) } } -impl Bytes31IntoU256 of Into { +pub(crate) impl Bytes31IntoU256 of Into { fn into(self: bytes31) -> u256 { let as_felt: felt252 = self.into(); as_felt.into() } } -impl Felt252TryIntoBytes31 of TryInto { +pub(crate) impl Felt252TryIntoBytes31 of TryInto { fn try_into(self: felt252) -> Option { bytes31_try_from_felt252(self) } } -// TODO(yuval): implement all `into`s using `integer::upcast(self)`. -impl U8IntoBytes31 of Into { +impl Bytes31Serde = core::serde::into_felt252_based::SerdeImpl; + +pub(crate) impl U8IntoBytes31 of Into { fn into(self: u8) -> bytes31 { - let as_felt: felt252 = self.into(); - as_felt.try_into().unwrap() + core::integer::upcast(self) } } impl U16IntoBytes31 of Into { fn into(self: u16) -> bytes31 { - let as_felt: felt252 = self.into(); - as_felt.try_into().unwrap() + core::integer::upcast(self) } } impl U32IntoBytes31 of Into { fn into(self: u32) -> bytes31 { - let as_felt: felt252 = self.into(); - as_felt.try_into().unwrap() + core::integer::upcast(self) } } impl U64IntoBytes31 of Into { fn into(self: u64) -> bytes31 { - let as_felt: felt252 = self.into(); - as_felt.try_into().unwrap() + core::integer::upcast(self) } } -impl U128IntoBytes31 of Into { +pub(crate) impl U128IntoBytes31 of Into { fn into(self: u128) -> bytes31 { - let as_felt: felt252 = self.into(); - as_felt.try_into().unwrap() + core::integer::upcast(self) } } @@ -94,7 +96,7 @@ impl U128IntoBytes31 of Into { // 3. len <= BYTES_IN_BYTES31. // If these assumptions are not met, it can corrupt the ByteArray. Thus, this should be a // private function. We could add masking/assertions but it would be more expansive. -fn split_bytes31(word: felt252, len: usize, index: usize) -> (felt252, felt252) { +pub(crate) fn split_bytes31(word: felt252, len: usize, index: usize) -> (felt252, felt252) { if index == 0 { return (0, word); } @@ -139,7 +141,7 @@ fn split_bytes31(word: felt252, len: usize, index: usize) -> (felt252, felt252) // Note: if `n_bytes >= BYTES_IN_BYTES31`, the behavior is undefined. If one wants to assert that in // the callsite, it's sufficient to assert that `n_bytes != BYTES_IN_BYTES31` because if // `n_bytes > 31` then `n_bytes - 16 > 15` and `one_shift_left_bytes_u128` would panic. -fn one_shift_left_bytes_felt252(n_bytes: usize) -> felt252 { +pub(crate) fn one_shift_left_bytes_felt252(n_bytes: usize) -> felt252 { if n_bytes < BYTES_IN_U128 { one_shift_left_bytes_u128(n_bytes).into() } else { @@ -150,7 +152,7 @@ fn one_shift_left_bytes_felt252(n_bytes: usize) -> felt252 { // Returns 1 << (8 * `n_bytes`) as u128, where `n_bytes` must be < BYTES_IN_U128. // // Panics if `n_bytes >= BYTES_IN_U128`. -fn one_shift_left_bytes_u128(n_bytes: usize) -> u128 { +pub(crate) fn one_shift_left_bytes_u128(n_bytes: usize) -> u128 { // TODO(yuval): change to match once it's supported for integers. if n_bytes == 0 { 0x1_u128 @@ -185,7 +187,7 @@ fn one_shift_left_bytes_u128(n_bytes: usize) -> u128 { } else if n_bytes == 15 { 0x1000000000000000000000000000000_u128 } else { - panic_with_felt252('n_bytes too big') + core::panic_with_felt252('n_bytes too big') } } diff --git a/corelib/src/clone.cairo b/corelib/src/clone.cairo index 27e986acd..3a27f9910 100644 --- a/corelib/src/clone.cairo +++ b/corelib/src/clone.cairo @@ -1,4 +1,5 @@ -trait Clone { +pub trait Clone { + #[must_use] fn clone(self: @T) -> T; } diff --git a/corelib/src/cmp.cairo b/corelib/src/cmp.cairo index 86738b06b..a45857099 100644 --- a/corelib/src/cmp.cairo +++ b/corelib/src/cmp.cairo @@ -1,11 +1,13 @@ -fn min, +Drop, +Copy>(a: T, b: T) -> T { +#[must_use] +pub fn min, +Drop, +Copy>(a: T, b: T) -> T { if a > b { return b; } a } -fn max, +Drop, +Copy>(a: T, b: T) -> T { +#[must_use] +pub fn max, +Drop, +Copy>(a: T, b: T) -> T { if a > b { return a; } diff --git a/corelib/src/debug.cairo b/corelib/src/debug.cairo index 8a840afda..f325f3477 100644 --- a/corelib/src/debug.cairo +++ b/corelib/src/debug.cairo @@ -1,10 +1,10 @@ -use array::ArrayTrait; -use traits::Into; -use option::Option; +use core::array::ArrayTrait; +use core::traits::Into; +use core::option::Option; // Usage: // -// use debug::PrintTrait; +// use core::debug::PrintTrait; // // 1.print(); // @@ -18,23 +18,23 @@ use option::Option; // arr.append('SomeVeryLongMessage'); // arr.print(); -extern fn print(message: Array) nopanic; +pub(crate) extern fn print(message: Array) nopanic; fn print_felt252(message: felt252) { print(array![message]); } -trait PrintTrait { +pub(crate) trait PrintTrait { fn print(self: T); } -impl Felt252PrintImpl of PrintTrait { +pub(crate) impl Felt252PrintImpl of PrintTrait { fn print(self: felt252) { print_felt252(self); } } -impl BoolPrintImpl of PrintTrait { +pub(crate) impl BoolPrintImpl of PrintTrait { fn print(self: bool) { if self { 'true'.print(); @@ -44,81 +44,89 @@ impl BoolPrintImpl of PrintTrait { } } -impl ContractAddressPrintImpl of PrintTrait { +pub(crate) impl ContractAddressPrintImpl of PrintTrait { fn print(self: starknet::ContractAddress) { Into::<_, felt252>::into(self).print(); } } -impl U8PrintImpl of PrintTrait { +pub(crate) impl U8PrintImpl of PrintTrait { fn print(self: u8) { Into::<_, felt252>::into(self).print(); } } -impl U16PrintImpl of PrintTrait { +pub(crate) impl U16PrintImpl of PrintTrait { fn print(self: u16) { Into::<_, felt252>::into(self).print(); } } -impl U32PrintImpl of PrintTrait { +pub(crate) impl U32PrintImpl of PrintTrait { fn print(self: u32) { Into::<_, felt252>::into(self).print(); } } -impl U64PrintImpl of PrintTrait { +pub(crate) impl U64PrintImpl of PrintTrait { fn print(self: u64) { Into::<_, felt252>::into(self).print(); } } -impl U128PrintImpl of PrintTrait { +pub(crate) impl U128PrintImpl of PrintTrait { fn print(self: u128) { Into::<_, felt252>::into(self).print(); } } -impl U256PrintImpl of PrintTrait { +pub(crate) impl U256PrintImpl of PrintTrait { fn print(self: u256) { Into::::into(self.low).print(); Into::::into(self.high).print(); } } -impl I8PrintImpl of PrintTrait { +pub(crate) impl I8PrintImpl of PrintTrait { fn print(self: i8) { Into::<_, felt252>::into(self).print(); } } -impl I16PrintImpl of PrintTrait { +pub(crate) impl I16PrintImpl of PrintTrait { fn print(self: i16) { Into::<_, felt252>::into(self).print(); } } -impl I32PrintImpl of PrintTrait { +pub(crate) impl I32PrintImpl of PrintTrait { fn print(self: i32) { Into::<_, felt252>::into(self).print(); } } -impl I64PrintImpl of PrintTrait { +pub(crate) impl I64PrintImpl of PrintTrait { fn print(self: i64) { Into::<_, felt252>::into(self).print(); } } -impl I128PrintImpl of PrintTrait { +pub(crate) impl I128PrintImpl of PrintTrait { fn print(self: i128) { Into::<_, felt252>::into(self).print(); } } -impl ArrayGenericPrintImpl of PrintTrait> { +pub(crate) impl ArrayGenericPrintImpl of PrintTrait> { fn print(mut self: Array) { print(self); } } + +/// Prints a byte array as a string. +pub fn print_byte_array_as_string(self: @ByteArray) { + let mut serialized = array![core::byte_array::BYTE_ARRAY_MAGIC]; + self.serialize(ref serialized); + print(serialized) +} + diff --git a/corelib/src/dict.cairo b/corelib/src/dict.cairo index e959d796a..b6de59fec 100644 --- a/corelib/src/dict.cairo +++ b/corelib/src/dict.cairo @@ -1,11 +1,11 @@ -use traits::{Index, Default}; +use core::traits::{Index, Default, Felt252DictValue}; -extern type Felt252Dict; -extern type SquashedFelt252Dict; -extern type Felt252DictEntry; +pub extern type Felt252Dict; +pub extern type SquashedFelt252Dict; +pub extern type Felt252DictEntry; impl SquashedFelt252DictDrop> of Drop>; -extern fn felt252_dict_new() -> Felt252Dict implicits(SegmentArena) nopanic; +pub(crate) extern fn felt252_dict_new() -> Felt252Dict implicits(SegmentArena) nopanic; extern fn felt252_dict_entry_get( dict: Felt252Dict, key: felt252 @@ -20,11 +20,11 @@ extern fn felt252_dict_entry_finalize( /// NOTE: Never use this libfunc directly. Use Felt252DictTrait::squash() instead. Using this /// libfunc directly will result in multiple unnecessary copies of the libfunc in the compiled CASM /// code. -extern fn felt252_dict_squash( +pub(crate) extern fn felt252_dict_squash( dict: Felt252Dict ) -> SquashedFelt252Dict implicits(RangeCheck, GasBuiltin, SegmentArena) nopanic; -trait Felt252DictTrait { +pub trait Felt252DictTrait { /// Inserts the given value for the given key. /// /// Requires the `Destruct` trait, as the previous value is dropped. @@ -34,6 +34,7 @@ trait Felt252DictTrait { /// Requires the `Copy` trait. fn get<+Copy>(ref self: Felt252Dict, key: felt252) -> T; fn squash(self: Felt252Dict) -> SquashedFelt252Dict nopanic; + #[must_use] fn entry(self: Felt252Dict, key: felt252) -> (Felt252DictEntry, T) nopanic; } impl Felt252DictImpl> of Felt252DictTrait { @@ -62,7 +63,7 @@ impl Felt252DictImpl> of Felt252DictTrait { } } -trait Felt252DictEntryTrait { +pub trait Felt252DictEntryTrait { fn finalize(self: Felt252DictEntry, new_value: T) -> Felt252Dict; } diff --git a/corelib/src/ec.cairo b/corelib/src/ec.cairo index f1a0c13c1..91123fecd 100644 --- a/corelib/src/ec.cairo +++ b/corelib/src/ec.cairo @@ -1,27 +1,27 @@ //! This module contains functions and constructs related to elliptic curve operations on the Stark //! curve. -use array::ArrayTrait; -use traits::{Into, TryInto}; -use zeroable::IsZeroResult; +use core::array::ArrayTrait; +use core::traits::{Into, TryInto}; +use core::zeroable::IsZeroResult; -mod stark_curve { +pub mod stark_curve { /// The STARK Curve is defined by the equation `y^2 = x^3 + ALPHA*x + BETA`. - const ALPHA: felt252 = 1; + pub const ALPHA: felt252 = 1; /// The STARK Curve is defined by the equation `y^2 = x^3 + ALPHA*x + BETA`. - const BETA: felt252 = 0x6f21413efbe40de150e596d72f7a8c5609ad26c15c915c1f4cdfcb99cee9e89; + pub const BETA: felt252 = 0x6f21413efbe40de150e596d72f7a8c5609ad26c15c915c1f4cdfcb99cee9e89; /// The order (number of points) of the STARK Curve. - const ORDER: felt252 = 0x800000000000010ffffffffffffffffb781126dcae7b2321e66a241adc64d2f; + pub const ORDER: felt252 = 0x800000000000010ffffffffffffffffb781126dcae7b2321e66a241adc64d2f; /// The x coordinate of the generator point used in the ECDSA signature. - const GEN_X: felt252 = 0x1ef15c18599971b7beced415a40f0c7deacfd9b0d1819e03d723d8bc943cfca; + pub const GEN_X: felt252 = 0x1ef15c18599971b7beced415a40f0c7deacfd9b0d1819e03d723d8bc943cfca; /// The y coordinate of the generator point used in the ECDSA signature. - const GEN_Y: felt252 = 0x5668060aa49730b7be4801df46ec62de53ecd11abe43a32873000c36e8dc1f; + pub const GEN_Y: felt252 = 0x5668060aa49730b7be4801df46ec62de53ecd11abe43a32873000c36e8dc1f; } -extern type EcOp; +pub extern type EcOp; #[derive(Copy, Drop)] -extern type EcPoint; -type NonZeroEcPoint = NonZero; +pub extern type EcPoint; +pub type NonZeroEcPoint = NonZero; /// Returns the zero point of the curve ("the point at infinity"). extern fn ec_point_zero() -> EcPoint nopanic; @@ -32,7 +32,7 @@ extern fn ec_point_try_new_nz(x: felt252, y: felt252) -> Option /// Returns `None` if no point of form (x, _) is on the curve. extern fn ec_point_from_x_nz(x: felt252) -> Option implicits(RangeCheck) nopanic; /// Unwraps a non-zero point into its (x, y) coordinates. -extern fn ec_point_unwrap(p: NonZeroEcPoint) -> (felt252, felt252) nopanic; +pub extern fn ec_point_unwrap(p: NonZeroEcPoint) -> (felt252, felt252) nopanic; /// Computes the negation of an elliptic curve point (-p). extern fn ec_neg(p: EcPoint) -> EcPoint nopanic; /// Checks whether the given `EcPoint` is the zero point. @@ -53,7 +53,7 @@ impl EcPointTryIntoNonZero of TryInto { // TODO(lior): Allow explicit clone() for EcState, since we don't allow implicit dup (Copy). #[derive(Drop)] -extern type EcState; +pub extern type EcState; /// Initializes an EC computation with the zero point. extern fn ec_state_init() -> EcState nopanic; @@ -69,8 +69,9 @@ extern fn ec_state_add_mul( extern fn ec_state_try_finalize_nz(s: EcState) -> Option nopanic; #[generate_trait] -impl EcStateImpl of EcStateTrait { +pub impl EcStateImpl of EcStateTrait { /// Initializes an EC computation with the zero point. + #[must_use] fn init() -> EcState { ec_state_init() } @@ -101,7 +102,7 @@ impl EcStateImpl of EcStateTrait { } #[generate_trait] -impl EcPointImpl of EcPointTrait { +pub impl EcPointImpl of EcPointTrait { /// Creates a new EC point from its (x, y) coordinates. #[inline(always)] fn new(x: felt252, y: felt252) -> Option { diff --git a/corelib/src/ecdsa.cairo b/corelib/src/ecdsa.cairo index c935be9ff..450e58641 100644 --- a/corelib/src/ecdsa.cairo +++ b/corelib/src/ecdsa.cairo @@ -1,7 +1,8 @@ -use ec::EcPointTrait; -use option::OptionTrait; -use traits::{Into, TryInto}; -use zeroable::IsZeroResult; +use core::{ec, ec::{EcPoint, EcPointTrait}}; +use core::option::OptionTrait; +use core::math; +use core::traits::{Into, TryInto}; +use core::zeroable::IsZeroResult; // Checks if (`signature_r`, `signature_s`) is a valid ECDSA signature for the given `public_key` // on the given `message`. @@ -21,7 +22,7 @@ use zeroable::IsZeroResult; // Returns: // `true` if the signature is valid and `false` otherwise. // TODO(lior): Make this function nopanic once possible. -fn check_ecdsa_signature( +pub fn check_ecdsa_signature( message_hash: felt252, public_key: felt252, signature_r: felt252, signature_s: felt252 ) -> bool { // TODO(orizi): Change to || once it does not prevent `a == 0` comparison optimization. @@ -37,7 +38,7 @@ fn check_ecdsa_signature( } // Check that the public key is the x coordinate of a point on the curve and get such a point. - let public_key_point = match ec::EcPointTrait::new_from_x(public_key) { + let public_key_point = match EcPointTrait::new_from_x(public_key) { Option::Some(point) => point, Option::None => { return false; }, }; @@ -98,7 +99,7 @@ fn check_ecdsa_signature( /// Receives a signature and the signed message hash. /// Returns the public key associated with the signer. -fn recover_public_key( +pub fn recover_public_key( message_hash: felt252, signature_r: felt252, signature_s: felt252, y_parity: bool ) -> Option { let mut signature_r_point = EcPointTrait::new_from_x(signature_r)?; @@ -128,7 +129,7 @@ fn recover_public_key( let r_nz = r_nz.try_into()?; let ord_nz: u256 = ec::stark_curve::ORDER.into(); let ord_nz = ord_nz.try_into()?; - let r_inv = math::inv_mod(r_nz, ord_nz)?; + let r_inv = math::u256_inv_mod(r_nz, ord_nz)?.into(); let s_div_r: felt252 = math::u256_mul_mod_n(signature_s.into(), r_inv, ord_nz).try_into()?; let z_div_r: felt252 = math::u256_mul_mod_n(message_hash.into(), r_inv, ord_nz).try_into()?; let s_div_rR: EcPoint = signature_r_point.mul(s_div_r); diff --git a/corelib/src/felt_252.cairo b/corelib/src/felt_252.cairo new file mode 100644 index 000000000..f1f9f1e0d --- /dev/null +++ b/corelib/src/felt_252.cairo @@ -0,0 +1,31 @@ +pub(crate) impl Felt252Zero of core::num::traits::Zero { + fn zero() -> felt252 { + 0 + } + + #[inline(always)] + fn is_zero(self: @felt252) -> bool { + *self == Felt252Zero::zero() + } + + #[inline(always)] + fn is_non_zero(self: @felt252) -> bool { + !self.is_zero() + } +} + +pub(crate) impl Felt252One of core::num::traits::One { + fn one() -> felt252 { + 1 + } + + #[inline(always)] + fn is_one(self: @felt252) -> bool { + *self == Felt252One::one() + } + + #[inline(always)] + fn is_non_one(self: @felt252) -> bool { + !self.is_one() + } +} diff --git a/corelib/src/fmt.cairo b/corelib/src/fmt.cairo new file mode 100644 index 000000000..4260f34f5 --- /dev/null +++ b/corelib/src/fmt.cairo @@ -0,0 +1,204 @@ +#[derive(Drop)] +pub struct Error {} + +/// Configuration for formatting. +#[derive(Default, Drop)] +pub struct Formatter { + /// The pending result of formatting. + pub buffer: ByteArray, +} + +/// A trait for standard formatting, using the empty format ("{}"). +pub trait Display { + fn fmt(self: @T, ref f: Formatter) -> Result<(), Error>; +} + +impl DisplayByteArray of Display { + fn fmt(self: @ByteArray, ref f: Formatter) -> Result<(), Error> { + f.buffer.append(self); + Result::Ok(()) + } +} + +impl DisplayInteger< + T, +to_byte_array::AppendFormattedToByteArray, +Into, +TryInto> +> of Display { + fn fmt(self: @T, ref f: Formatter) -> Result<(), Error> { + // TODO(yuval): determine base according to Formatter parameters. + let base: T = 10_u8.into(); + self.append_formatted_to_byte_array(ref f.buffer, base.try_into().unwrap()); + Result::Ok(()) + } +} + +impl DisplayNonZero, +Copy, +Drop> of Display> { + fn fmt(self: @NonZero, ref f: Formatter) -> Result<(), Error> { + let value: T = (*self).into(); + write!(f, "{value}") + } +} + +impl DisplayBool of Display { + fn fmt(self: @bool, ref f: Formatter) -> Result<(), Error> { + if *self { + write!(f, "true") + } else { + write!(f, "false") + } + } +} + +impl DisplaySnapshot> of Display<@T> { + fn fmt(self: @@T, ref f: Formatter) -> Result<(), Error> { + Display::fmt(*self, ref f) + } +} + +/// A trait for debug formatting, using the empty format ("{:?}"). +pub trait Debug { + fn fmt(self: @T, ref f: Formatter) -> Result<(), Error>; +} + +impl DebugByteArray of Debug { + fn fmt(self: @ByteArray, ref f: Formatter) -> Result<(), Error> { + write!(f, "\"")?; + Display::fmt(self, ref f)?; + write!(f, "\"") + } +} + +impl DebugInteger< + T, +to_byte_array::AppendFormattedToByteArray, +Into, +TryInto> +> of Debug { + fn fmt(self: @T, ref f: Formatter) -> Result<(), Error> { + Display::fmt(self, ref f) + } +} + +impl DebugNonZero, +Copy, +Drop> of Debug> { + fn fmt(self: @NonZero, ref f: Formatter) -> Result<(), Error> { + let value: T = (*self).into(); + write!(f, "{value:?}") + } +} + +impl DebugBool of Debug { + fn fmt(self: @bool, ref f: Formatter) -> Result<(), Error> { + Display::fmt(self, ref f) + } +} + +impl DebugSnapshot> of Debug<@T> { + fn fmt(self: @@T, ref f: Formatter) -> Result<(), Error> { + write!(f, "@")?; + Debug::fmt(*self, ref f) + } +} + +impl DebugTuple0 of Debug<()> { + fn fmt(self: @(), ref f: Formatter) -> Result<(), Error> { + write!(f, "()") + } +} + +impl DebugTuple1> of Debug<(E0,)> { + fn fmt(self: @(E0,), ref f: Formatter) -> Result<(), Error> { + let (e0,) = self; + write!(f, "(")?; + E0Debug::fmt(e0, ref f)?; + write!(f, ",)") + } +} + +impl DebugTuple2, impl E1Debug: Debug> of Debug<(E0, E1)> { + fn fmt(self: @(E0, E1), ref f: Formatter) -> Result<(), Error> { + let (e0, e1) = self; + write!(f, "(")?; + E0Debug::fmt(e0, ref f)?; + write!(f, ", ")?; + E1Debug::fmt(e1, ref f)?; + write!(f, ")") + } +} + +impl DebugTuple3< + E0, E1, E2, impl E0Debug: Debug, impl E1Debug: Debug, impl E2Debug: Debug +> of Debug<(E0, E1, E2)> { + fn fmt(self: @(E0, E1, E2), ref f: Formatter) -> Result<(), Error> { + let (e0, e1, e2) = self; + write!(f, "(")?; + E0Debug::fmt(e0, ref f)?; + write!(f, ", ")?; + E1Debug::fmt(e1, ref f)?; + write!(f, ", ")?; + E2Debug::fmt(e2, ref f)?; + write!(f, ")") + } +} + +impl DebugTuple4< + E0, + E1, + E2, + E3, + impl E0Debug: Debug, + impl E1Debug: Debug, + impl E2Debug: Debug, + impl E3Debug: Debug +> of Debug<(E0, E1, E2, E3)> { + fn fmt(self: @(E0, E1, E2, E3), ref f: Formatter) -> Result<(), Error> { + let (e0, e1, e2, e3) = self; + write!(f, "(")?; + E0Debug::fmt(e0, ref f)?; + write!(f, ", ")?; + E1Debug::fmt(e1, ref f)?; + write!(f, ", ")?; + E2Debug::fmt(e2, ref f)?; + write!(f, ", ")?; + E3Debug::fmt(e3, ref f)?; + write!(f, ")") + } +} + +impl ArrayTDebug> of Debug> { + fn fmt(self: @Array, ref f: Formatter) -> Result<(), Error> { + Debug::fmt(@self.span(), ref f) + } +} + +impl SpanTDebug> of Debug> { + fn fmt(self: @Span, ref f: Formatter) -> Result<(), Error> { + let mut self = *self; + write!(f, "[")?; + loop { + match self.pop_front() { + Option::Some(value) => { + if Debug::fmt(value, ref f).is_err() { + break Result::Err(Error {}); + }; + if self.is_empty() { + break Result::Ok(()); + } + if write!(f, ", ").is_err() { + break Result::Err(Error {}); + }; + }, + Option::None => { break Result::Ok(()); } + }; + }?; + write!(f, "]") + } +} + +/// Impls for `Debug` for types that can be converted into `felt252` using the `Into` trait. +/// Usage example: +/// ```ignore +/// impl MyTypeDebug = core::fmt::into_felt252_based::DebugImpl;` +/// ``` +pub mod into_felt252_based { + pub impl DebugImpl, +Copy> of core::fmt::Debug { + fn fmt(self: @T, ref f: core::fmt::Formatter) -> Result<(), core::fmt::Error> { + core::fmt::DebugInteger::::fmt(@(*self).into(), ref f) + } + } +} diff --git a/corelib/src/gas.cairo b/corelib/src/gas.cairo index 229dce2b9..6ef2c70af 100644 --- a/corelib/src/gas.cairo +++ b/corelib/src/gas.cairo @@ -1,9 +1,9 @@ #[derive(Copy, Drop)] -extern type BuiltinCosts; -extern type GasBuiltin; +pub extern type BuiltinCosts; +pub extern type GasBuiltin; -extern fn withdraw_gas() -> Option<()> implicits(RangeCheck, GasBuiltin) nopanic; -extern fn withdraw_gas_all( +pub extern fn withdraw_gas() -> Option<()> implicits(RangeCheck, GasBuiltin) nopanic; +pub extern fn withdraw_gas_all( costs: BuiltinCosts ) -> Option<()> implicits(RangeCheck, GasBuiltin) nopanic; -extern fn get_builtin_costs() -> BuiltinCosts nopanic; +pub extern fn get_builtin_costs() -> BuiltinCosts nopanic; diff --git a/corelib/src/hash.cairo b/corelib/src/hash.cairo index 4be6b59a2..5556f0244 100644 --- a/corelib/src/hash.cairo +++ b/corelib/src/hash.cairo @@ -1,35 +1,40 @@ -use traits::Into; +use core::traits::Into; /// A trait for hash state accumulators. -trait HashStateTrait { +pub trait HashStateTrait { + #[must_use] fn update(self: S, value: felt252) -> S; + #[must_use] fn finalize(self: S) -> felt252; } /// A trait for values that can be hashed. -trait Hash> { +pub trait Hash> { /// Updates the hash state with the given value. + #[must_use] fn update_state(state: S, value: T) -> S; } /// Trait for hashing values. /// Used for backwards compatibility. /// NOTE: Implement `Hash` instead of this trait if possible. -trait LegacyHash { +pub trait LegacyHash { + #[must_use] fn hash(state: felt252, value: T) -> felt252; } /// Implementation of `LegacyHash` for types that have `Hash` for backwards compatibility. -impl LegacyHashForHash> of LegacyHash { +impl LegacyHashForHash> of LegacyHash { #[inline(always)] fn hash(state: felt252, value: T) -> felt252 { - pedersen::HashState { state }.update_with(value).state + core::pedersen::HashState { state }.update_with(value).state } } /// Extension trait for hash state accumulators. -trait HashStateExTrait { +pub trait HashStateExTrait { /// Updates the hash state with the given value. + #[must_use] fn update_with(self: S, value: T) -> S; } @@ -53,8 +58,8 @@ impl HashFelt252> of Hash { /// impl MyTypeHash, +Drop> = /// core::hash::into_felt252_based::HashImpl;` /// ``` -mod into_felt252_based { - impl HashImpl< +pub mod into_felt252_based { + pub impl HashImpl< T, S, +Into, +super::HashStateTrait, +Drop > of super::Hash { #[inline(always)] diff --git a/corelib/src/integer.cairo b/corelib/src/integer.cairo index 60dab9d72..9e65b11c0 100644 --- a/corelib/src/integer.cairo +++ b/corelib/src/integer.cairo @@ -1,18 +1,17 @@ -use option::OptionTrait; -use result::ResultTrait; -use traits::{Into, TryInto, Default, Felt252DictValue}; -use zeroable::{IsZeroResult, NonZeroIntoImpl, Zeroable}; -use array::ArrayTrait; -use array::SpanTrait; +use core::option::OptionTrait; +use core::result::ResultTrait; +use core::traits::{Into, TryInto, Default, Felt252DictValue}; +use core::zeroable::{IsZeroResult, NonZeroIntoImpl, Zeroable}; +use core::array::ArrayTrait; +use core::array::SpanTrait; // TODO(spapini): Add method for const creation from Integer. -trait NumericLiteral; +pub trait NumericLiteral; impl NumericLiteralfelt252 of NumericLiteral; #[derive(Copy, Drop)] -extern type u128; +pub extern type u128; impl NumericLiteralu128 of NumericLiteral; -extern fn u128_const() -> u128 nopanic; impl U128Serde = core::serde::into_felt252_based::SerdeImpl; @@ -26,27 +25,27 @@ extern fn u128s_from_felt252(a: felt252) -> U128sFromFelt252Result implicits(Ran fn u128_try_from_felt252(a: felt252) -> Option implicits(RangeCheck) nopanic { match u128s_from_felt252(a) { U128sFromFelt252Result::Narrow(x) => Option::Some(x), - U128sFromFelt252Result::Wide(x) => Option::None, + U128sFromFelt252Result::Wide(_x) => Option::None, } } -extern fn u128_to_felt252(a: u128) -> felt252 nopanic; +pub(crate) extern fn u128_to_felt252(a: u128) -> felt252 nopanic; -extern fn u128_overflowing_add( +pub extern fn u128_overflowing_add( lhs: u128, rhs: u128 ) -> Result implicits(RangeCheck) nopanic; -extern fn u128_overflowing_sub( +pub extern fn u128_overflowing_sub( lhs: u128, rhs: u128 ) -> Result implicits(RangeCheck) nopanic; -fn u128_wrapping_add(lhs: u128, rhs: u128) -> u128 implicits(RangeCheck) nopanic { +pub fn u128_wrapping_add(lhs: u128, rhs: u128) -> u128 implicits(RangeCheck) nopanic { match u128_overflowing_add(lhs, rhs) { Result::Ok(x) => x, Result::Err(x) => x, } } -fn u128_wrapping_sub(a: u128, b: u128) -> u128 implicits(RangeCheck) nopanic { +pub fn u128_wrapping_sub(a: u128, b: u128) -> u128 implicits(RangeCheck) nopanic { match u128_overflowing_sub(a, b) { Result::Ok(x) => x, Result::Err(x) => x, @@ -57,7 +56,7 @@ fn u128_wrapping_sub(a: u128, b: u128) -> u128 implicits(RangeCheck) nopanic { /// /// The guarantee is verified by `u128_mul_guarantee_verify`, which is the only way to destruct this /// type. This way, one can trust that the guarantee holds although it has not yet been verified. -extern type U128MulGuarantee; +pub extern type U128MulGuarantee; /// Multiplies two u128s and returns a `U128MulGuarantee` for the result of `a * b`. extern fn u128_guarantee_mul(a: u128, b: u128) -> (u128, u128, U128MulGuarantee) nopanic; @@ -67,7 +66,7 @@ extern fn u128_mul_guarantee_verify(guarantee: U128MulGuarantee) implicits(Range /// Multiplies two u128s and returns `(high, low)` - the 128-bit parts of the result. #[inline(always)] -fn u128_wide_mul(a: u128, b: u128) -> (u128, u128) nopanic { +pub fn u128_wide_mul(a: u128, b: u128) -> (u128, u128) nopanic { let (high, low, _) = u128_guarantee_mul(a, b); (high, low) } @@ -78,9 +77,9 @@ impl U128MulGuaranteeDestruct of Destruct { } } -extern fn u128_sqrt(value: u128) -> u64 implicits(RangeCheck) nopanic; +pub extern fn u128_sqrt(value: u128) -> u64 implicits(RangeCheck) nopanic; -fn u128_overflowing_mul(lhs: u128, rhs: u128) -> (u128, bool) implicits(RangeCheck) nopanic { +pub fn u128_overflowing_mul(lhs: u128, rhs: u128) -> (u128, bool) implicits(RangeCheck) nopanic { let (top_word, bottom_word) = u128_wide_mul(lhs, rhs); match u128_to_felt252(top_word) { 0 => (bottom_word, false), @@ -92,7 +91,7 @@ fn u128_overflowing_mul(lhs: u128, rhs: u128) -> (u128, bool) implicits(RangeChe 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, + Result::Err(_r) => Option::None, } } @@ -112,7 +111,7 @@ impl U128AddEq of AddEq { 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, + Result::Err(_r) => Option::None, } } @@ -156,15 +155,15 @@ fn u128_try_as_non_zero(a: u128) -> Option> nopanic { } } -impl U128TryIntoNonZero of TryInto> { +pub(crate) impl U128TryIntoNonZero of TryInto> { fn try_into(self: u128) -> Option> { - Option::Some(u128_as_non_zero(self)) + u128_try_as_non_zero(self) } } impl U128Div of Div { fn div(lhs: u128, rhs: u128) -> u128 { - let (q, r) = u128_safe_divmod(lhs, rhs.try_into().expect('Division by 0')); + let (q, _r) = u128_safe_divmod(lhs, rhs.try_into().expect('Division by 0')); q } } @@ -177,7 +176,7 @@ impl U128DivEq of DivEq { impl U128Rem of Rem { fn rem(lhs: u128, rhs: u128) -> u128 { - let (q, r) = u128_safe_divmod(lhs, rhs.try_into().expect('Division by 0')); + let (_q, r) = u128_safe_divmod(lhs, rhs.try_into().expect('Division by 0')); r } } @@ -194,7 +193,7 @@ impl U128DivRem of DivRem { } } -extern fn u128_safe_divmod( +pub extern fn u128_safe_divmod( lhs: u128, rhs: NonZero ) -> (u128, u128) implicits(RangeCheck) nopanic; @@ -230,7 +229,7 @@ impl U128PartialOrd of PartialOrd { } } -extern type Bitwise; +pub extern type Bitwise; extern fn bitwise(lhs: u128, rhs: u128) -> (u128, u128, u128) implicits(Bitwise) nopanic; impl U128BitAnd of BitAnd { #[inline(always)] @@ -259,14 +258,19 @@ impl U128BitNot of BitNot { } } -extern fn u128_is_zero(a: u128) -> IsZeroResult implicits() nopanic; +impl U128BitSize of core::num::traits::BitSize { + fn bits() -> usize { + 128 + } +} + +pub(crate) extern fn u128_is_zero(a: u128) -> IsZeroResult implicits() nopanic; -extern fn u128_byte_reverse(input: u128) -> u128 implicits(Bitwise) nopanic; +pub extern fn u128_byte_reverse(input: u128) -> u128 implicits(Bitwise) nopanic; #[derive(Copy, Drop)] -extern type u8; +pub 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 Overflow', u8_from_felt252)] @@ -306,17 +310,17 @@ impl U8PartialOrd of PartialOrd { } } -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; +pub extern fn u8_overflowing_add(lhs: u8, rhs: u8) -> Result implicits(RangeCheck) nopanic; +pub extern fn u8_overflowing_sub(lhs: u8, rhs: u8) -> Result implicits(RangeCheck) nopanic; -fn u8_wrapping_add(lhs: u8, rhs: u8) -> u8 implicits(RangeCheck) nopanic { +pub fn u8_wrapping_add(lhs: u8, rhs: u8) -> u8 implicits(RangeCheck) nopanic { match u8_overflowing_add(lhs, rhs) { Result::Ok(x) => x, Result::Err(x) => x, } } -fn u8_wrapping_sub(lhs: u8, rhs: u8) -> u8 implicits(RangeCheck) nopanic { +pub fn u8_wrapping_sub(lhs: u8, rhs: u8) -> u8 implicits(RangeCheck) nopanic { match u8_overflowing_sub(lhs, rhs) { Result::Ok(x) => x, Result::Err(x) => x, @@ -326,7 +330,7 @@ fn u8_wrapping_sub(lhs: u8, rhs: u8) -> u8 implicits(RangeCheck) nopanic { 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, + Result::Err(_r) => Option::None, } } @@ -345,7 +349,7 @@ impl U8AddEq of AddEq { 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, + Result::Err(_r) => Option::None, } } @@ -361,8 +365,8 @@ impl U8SubEq of SubEq { } } -extern fn u8_wide_mul(lhs: u8, rhs: u8) -> u16 implicits() nopanic; -extern fn u8_sqrt(value: u8) -> u8 implicits(RangeCheck) nopanic; +pub extern fn u8_wide_mul(lhs: u8, rhs: u8) -> u16 implicits() nopanic; +pub extern fn u8_sqrt(value: u8) -> u8 implicits(RangeCheck) nopanic; impl U8Mul of Mul { fn mul(lhs: u8, rhs: u8) -> u8 { @@ -377,7 +381,7 @@ impl U8MulEq of MulEq { } extern fn u8_is_zero(a: u8) -> IsZeroResult implicits() nopanic; -extern fn u8_safe_divmod(lhs: u8, rhs: NonZero) -> (u8, u8) implicits(RangeCheck) nopanic; +pub extern fn u8_safe_divmod(lhs: u8, rhs: NonZero) -> (u8, u8) implicits(RangeCheck) nopanic; #[panic_with('u8 is 0', u8_as_non_zero)] fn u8_try_as_non_zero(a: u8) -> Option> nopanic { @@ -389,13 +393,13 @@ fn u8_try_as_non_zero(a: u8) -> Option> nopanic { impl U8TryIntoNonZero of TryInto> { fn try_into(self: u8) -> Option> { - Option::Some(u8_as_non_zero(self)) + u8_try_as_non_zero(self) } } impl U8Div of Div { fn div(lhs: u8, rhs: u8) -> u8 { - let (q, r) = u8_safe_divmod(lhs, rhs.try_into().expect('Division by 0')); + let (q, _r) = u8_safe_divmod(lhs, rhs.try_into().expect('Division by 0')); q } } @@ -408,7 +412,7 @@ impl U8DivEq of DivEq { impl U8Rem of Rem { fn rem(lhs: u8, rhs: u8) -> u8 { - let (q, r) = u8_safe_divmod(lhs, rhs.try_into().expect('Division by 0')); + let (_q, r) = u8_safe_divmod(lhs, rhs.try_into().expect('Division by 0')); r } } @@ -453,10 +457,15 @@ impl U8BitOr of BitOr { } } +impl U8BitSize of core::num::traits::BitSize { + fn bits() -> usize { + 8 + } +} + #[derive(Copy, Drop)] -extern type u16; +pub 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 Overflow', u16_from_felt252)] @@ -496,17 +505,21 @@ impl U16PartialOrd of PartialOrd { } } -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; +pub extern fn u16_overflowing_add( + lhs: u16, rhs: u16 +) -> Result implicits(RangeCheck) nopanic; +pub extern fn u16_overflowing_sub( + lhs: u16, rhs: u16 +) -> Result implicits(RangeCheck) nopanic; -fn u16_wrapping_add(lhs: u16, rhs: u16) -> u16 implicits(RangeCheck) nopanic { +pub fn u16_wrapping_add(lhs: u16, rhs: u16) -> u16 implicits(RangeCheck) nopanic { match u16_overflowing_add(lhs, rhs) { Result::Ok(x) => x, Result::Err(x) => x, } } -fn u16_wrapping_sub(lhs: u16, rhs: u16) -> u16 implicits(RangeCheck) nopanic { +pub fn u16_wrapping_sub(lhs: u16, rhs: u16) -> u16 implicits(RangeCheck) nopanic { match u16_overflowing_sub(lhs, rhs) { Result::Ok(x) => x, Result::Err(x) => x, @@ -516,7 +529,7 @@ fn u16_wrapping_sub(lhs: u16, rhs: u16) -> u16 implicits(RangeCheck) nopanic { 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, + Result::Err(_r) => Option::None, } } @@ -535,7 +548,7 @@ impl U16AddEq of AddEq { 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, + Result::Err(_r) => Option::None, } } @@ -551,8 +564,8 @@ impl U16SubEq of SubEq { } } -extern fn u16_wide_mul(lhs: u16, rhs: u16) -> u32 implicits() nopanic; -extern fn u16_sqrt(value: u16) -> u8 implicits(RangeCheck) nopanic; +pub extern fn u16_wide_mul(lhs: u16, rhs: u16) -> u32 implicits() nopanic; +pub extern fn u16_sqrt(value: u16) -> u8 implicits(RangeCheck) nopanic; impl U16Mul of Mul { fn mul(lhs: u16, rhs: u16) -> u16 { @@ -567,7 +580,9 @@ impl U16MulEq of MulEq { } extern fn u16_is_zero(a: u16) -> IsZeroResult implicits() nopanic; -extern fn u16_safe_divmod(lhs: u16, rhs: NonZero) -> (u16, u16) implicits(RangeCheck) nopanic; +pub extern fn u16_safe_divmod( + lhs: u16, rhs: NonZero +) -> (u16, u16) implicits(RangeCheck) nopanic; #[panic_with('u16 is 0', u16_as_non_zero)] fn u16_try_as_non_zero(a: u16) -> Option> nopanic { @@ -579,13 +594,13 @@ fn u16_try_as_non_zero(a: u16) -> Option> nopanic { impl U16TryIntoNonZero of TryInto> { fn try_into(self: u16) -> Option> { - Option::Some(u16_as_non_zero(self)) + u16_try_as_non_zero(self) } } impl U16Div of Div { fn div(lhs: u16, rhs: u16) -> u16 { - let (q, r) = u16_safe_divmod(lhs, rhs.try_into().expect('Division by 0')); + let (q, _r) = u16_safe_divmod(lhs, rhs.try_into().expect('Division by 0')); q } } @@ -598,7 +613,7 @@ impl U16DivEq of DivEq { impl U16Rem of Rem { fn rem(lhs: u16, rhs: u16) -> u16 { - let (q, r) = u16_safe_divmod(lhs, rhs.try_into().expect('Division by 0')); + let (_q, r) = u16_safe_divmod(lhs, rhs.try_into().expect('Division by 0')); r } } @@ -643,10 +658,15 @@ impl U16BitOr of BitOr { } } +impl U16BitSize of core::num::traits::BitSize { + fn bits() -> usize { + 16 + } +} + #[derive(Copy, Drop)] -extern type u32; +pub 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 Overflow', u32_from_felt252)] @@ -686,17 +706,21 @@ impl U32PartialOrd of PartialOrd { } } -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; +pub extern fn u32_overflowing_add( + lhs: u32, rhs: u32 +) -> Result implicits(RangeCheck) nopanic; +pub extern fn u32_overflowing_sub( + lhs: u32, rhs: u32 +) -> Result implicits(RangeCheck) nopanic; -fn u32_wrapping_add(lhs: u32, rhs: u32) -> u32 implicits(RangeCheck) nopanic { +pub fn u32_wrapping_add(lhs: u32, rhs: u32) -> u32 implicits(RangeCheck) nopanic { match u32_overflowing_add(lhs, rhs) { Result::Ok(x) => x, Result::Err(x) => x, } } -fn u32_wrapping_sub(lhs: u32, rhs: u32) -> u32 implicits(RangeCheck) nopanic { +pub fn u32_wrapping_sub(lhs: u32, rhs: u32) -> u32 implicits(RangeCheck) nopanic { match u32_overflowing_sub(lhs, rhs) { Result::Ok(x) => x, Result::Err(x) => x, @@ -706,7 +730,7 @@ fn u32_wrapping_sub(lhs: u32, rhs: u32) -> u32 implicits(RangeCheck) nopanic { 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, + Result::Err(_r) => Option::None, } } @@ -725,7 +749,7 @@ impl U32AddEq of AddEq { 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, + Result::Err(_r) => Option::None, } } @@ -741,8 +765,8 @@ impl U32SubEq of SubEq { } } -extern fn u32_wide_mul(lhs: u32, rhs: u32) -> u64 implicits() nopanic; -extern fn u32_sqrt(value: u32) -> u16 implicits(RangeCheck) nopanic; +pub extern fn u32_wide_mul(lhs: u32, rhs: u32) -> u64 implicits() nopanic; +pub extern fn u32_sqrt(value: u32) -> u16 implicits(RangeCheck) nopanic; impl U32Mul of Mul { fn mul(lhs: u32, rhs: u32) -> u32 { @@ -757,7 +781,9 @@ impl U32MulEq of MulEq { } extern fn u32_is_zero(a: u32) -> IsZeroResult implicits() nopanic; -extern fn u32_safe_divmod(lhs: u32, rhs: NonZero) -> (u32, u32) implicits(RangeCheck) nopanic; +pub extern fn u32_safe_divmod( + lhs: u32, rhs: NonZero +) -> (u32, u32) implicits(RangeCheck) nopanic; #[panic_with('u32 is 0', u32_as_non_zero)] fn u32_try_as_non_zero(a: u32) -> Option> nopanic { @@ -767,15 +793,15 @@ fn u32_try_as_non_zero(a: u32) -> Option> nopanic { } } -impl U32TryIntoNonZero of TryInto> { +pub(crate) impl U32TryIntoNonZero of TryInto> { fn try_into(self: u32) -> Option> { - Option::Some(u32_as_non_zero(self)) + u32_try_as_non_zero(self) } } impl U32Div of Div { fn div(lhs: u32, rhs: u32) -> u32 { - let (q, r) = u32_safe_divmod(lhs, rhs.try_into().expect('Division by 0')); + let (q, _r) = u32_safe_divmod(lhs, rhs.try_into().expect('Division by 0')); q } } @@ -788,7 +814,7 @@ impl U32DivEq of DivEq { impl U32Rem of Rem { fn rem(lhs: u32, rhs: u32) -> u32 { - let (q, r) = u32_safe_divmod(lhs, rhs.try_into().expect('Division by 0')); + let (_q, r) = u32_safe_divmod(lhs, rhs.try_into().expect('Division by 0')); r } } @@ -833,10 +859,15 @@ impl U32BitOr of BitOr { } } +impl U32BitSize of core::num::traits::BitSize { + fn bits() -> usize { + 32 + } +} + #[derive(Copy, Drop)] -extern type u64; +pub 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 Overflow', u64_from_felt252)] @@ -876,17 +907,21 @@ impl U64PartialOrd of PartialOrd { } } -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; +pub extern fn u64_overflowing_add( + lhs: u64, rhs: u64 +) -> Result implicits(RangeCheck) nopanic; +pub extern fn u64_overflowing_sub( + lhs: u64, rhs: u64 +) -> Result implicits(RangeCheck) nopanic; -fn u64_wrapping_add(lhs: u64, rhs: u64) -> u64 implicits(RangeCheck) nopanic { +pub fn u64_wrapping_add(lhs: u64, rhs: u64) -> u64 implicits(RangeCheck) nopanic { match u64_overflowing_add(lhs, rhs) { Result::Ok(x) => x, Result::Err(x) => x, } } -fn u64_wrapping_sub(lhs: u64, rhs: u64) -> u64 implicits(RangeCheck) nopanic { +pub fn u64_wrapping_sub(lhs: u64, rhs: u64) -> u64 implicits(RangeCheck) nopanic { match u64_overflowing_sub(lhs, rhs) { Result::Ok(x) => x, Result::Err(x) => x, @@ -896,7 +931,7 @@ fn u64_wrapping_sub(lhs: u64, rhs: u64) -> u64 implicits(RangeCheck) nopanic { 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, + Result::Err(_r) => Option::None, } } @@ -915,7 +950,7 @@ impl U64AddEq of AddEq { 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, + Result::Err(_r) => Option::None, } } @@ -931,8 +966,8 @@ impl U64SubEq of SubEq { } } -extern fn u64_wide_mul(lhs: u64, rhs: u64) -> u128 implicits() nopanic; -extern fn u64_sqrt(value: u64) -> u32 implicits(RangeCheck) nopanic; +pub extern fn u64_wide_mul(lhs: u64, rhs: u64) -> u128 implicits() nopanic; +pub extern fn u64_sqrt(value: u64) -> u32 implicits(RangeCheck) nopanic; impl U64Mul of Mul { fn mul(lhs: u64, rhs: u64) -> u64 { @@ -947,7 +982,9 @@ impl U64MulEq of MulEq { } extern fn u64_is_zero(a: u64) -> IsZeroResult implicits() nopanic; -extern fn u64_safe_divmod(lhs: u64, rhs: NonZero) -> (u64, u64) implicits(RangeCheck) nopanic; +pub extern fn u64_safe_divmod( + lhs: u64, rhs: NonZero +) -> (u64, u64) implicits(RangeCheck) nopanic; #[panic_with('u64 is 0', u64_as_non_zero)] fn u64_try_as_non_zero(a: u64) -> Option> nopanic { @@ -959,13 +996,13 @@ fn u64_try_as_non_zero(a: u64) -> Option> nopanic { impl U64TryIntoNonZero of TryInto> { fn try_into(self: u64) -> Option> { - Option::Some(u64_as_non_zero(self)) + u64_try_as_non_zero(self) } } impl U64Div of Div { fn div(lhs: u64, rhs: u64) -> u64 { - let (q, r) = u64_safe_divmod(lhs, rhs.try_into().expect('Division by 0')); + let (q, _r) = u64_safe_divmod(lhs, rhs.try_into().expect('Division by 0')); q } } @@ -978,7 +1015,7 @@ impl U64DivEq of DivEq { impl U64Rem of Rem { fn rem(lhs: u64, rhs: u64) -> u64 { - let (q, r) = u64_safe_divmod(lhs, rhs.try_into().expect('Division by 0')); + let (_q, r) = u64_safe_divmod(lhs, rhs.try_into().expect('Division by 0')); r } } @@ -1023,14 +1060,20 @@ impl U64BitOr of BitOr { } } +impl U64BitSize of core::num::traits::BitSize { + fn bits() -> usize { + 64 + } +} + #[derive(Copy, Drop, Hash, PartialEq, Serde, starknet::Store)] -struct u256 { - low: u128, - high: u128, +pub struct u256 { + pub low: u128, + pub high: u128, } impl NumericLiteralU256 of NumericLiteral; -fn u256_overflowing_add(lhs: u256, rhs: u256) -> (u256, bool) implicits(RangeCheck) nopanic { +pub fn u256_overflowing_add(lhs: u256, rhs: u256) -> (u256, bool) implicits(RangeCheck) nopanic { let (high, overflow) = match u128_overflowing_add(lhs.high, rhs.high) { Result::Ok(high) => (high, false), Result::Err(high) => (high, true), @@ -1046,7 +1089,7 @@ fn u256_overflowing_add(lhs: u256, rhs: u256) -> (u256, bool) implicits(RangeChe } } -fn u256_overflow_sub(lhs: u256, rhs: u256) -> (u256, bool) implicits(RangeCheck) nopanic { +pub fn u256_overflow_sub(lhs: u256, rhs: u256) -> (u256, bool) implicits(RangeCheck) nopanic { let (high, overflow) = match u128_overflowing_sub(lhs.high, rhs.high) { Result::Ok(high) => (high, false), Result::Err(high) => (high, true), @@ -1062,7 +1105,7 @@ fn u256_overflow_sub(lhs: u256, rhs: u256) -> (u256, bool) implicits(RangeCheck) } } -fn u256_overflow_mul(lhs: u256, rhs: u256) -> (u256, bool) { +pub fn u256_overflow_mul(lhs: u256, rhs: u256) -> (u256, bool) { let (high1, low) = u128_wide_mul(lhs.low, rhs.low); let (overflow_value1, high2) = u128_wide_mul(lhs.low, rhs.high); let (overflow_value2, high3) = u128_wide_mul(lhs.high, rhs.low); @@ -1210,7 +1253,7 @@ fn u256_safe_div_rem(lhs: u256, rhs: NonZero) -> (u256, u256) implicits(Ra let (q, r, _) = u256_safe_divmod(lhs, rhs); (q, r) } -extern fn u256_sqrt(a: u256) -> u128 implicits(RangeCheck) nopanic; +pub extern fn u256_sqrt(a: u256) -> u128 implicits(RangeCheck) nopanic; #[panic_with('u256 is 0', u256_as_non_zero)] fn u256_try_as_non_zero(a: u256) -> Option> nopanic { @@ -1220,15 +1263,15 @@ fn u256_try_as_non_zero(a: u256) -> Option> nopanic { } } -impl U256TryIntoNonZero of TryInto> { +pub(crate) impl U256TryIntoNonZero of TryInto> { fn try_into(self: u256) -> Option> { - Option::Some(u256_as_non_zero(self)) + u256_try_as_non_zero(self) } } impl U256Div of Div { fn div(lhs: u256, rhs: u256) -> u256 { - let (q, r) = u256_safe_div_rem(lhs, rhs.try_into().expect('Division by 0')); + let (q, _r) = u256_safe_div_rem(lhs, rhs.try_into().expect('Division by 0')); q } } @@ -1241,7 +1284,7 @@ impl U256DivEq of DivEq { impl U256Rem of Rem { fn rem(lhs: u256, rhs: u256) -> u256 { - let (q, r) = u256_safe_div_rem(lhs, rhs.try_into().expect('Division by 0')); + let (_q, r) = u256_safe_div_rem(lhs, rhs.try_into().expect('Division by 0')); r } } @@ -1264,12 +1307,18 @@ impl U256BitNot of BitNot { } } +impl U256BitSize of core::num::traits::BitSize { + fn bits() -> usize { + 256 + } +} + #[derive(Copy, Drop, Hash, PartialEq, Serde)] -struct u512 { - limb0: u128, - limb1: u128, - limb2: u128, - limb3: u128, +pub struct u512 { + pub limb0: u128, + pub limb1: u128, + pub limb2: u128, + pub limb3: u128, } // Returns the result of u128 addition, including an overflow word. @@ -1280,7 +1329,7 @@ fn u128_add_with_carry(a: u128, b: u128) -> (u128, u128) nopanic { } } -fn u256_wide_mul(a: u256, b: u256) -> u512 nopanic { +pub fn u256_wide_mul(a: u256, b: u256) -> u512 nopanic { let (limb1, limb0) = u128_wide_mul(a.low, b.low); let (limb2, limb1_part) = u128_wide_mul(a.low, b.high); let (limb1, limb1_overflow0) = u128_add_with_carry(limb1, limb1_part); @@ -1303,7 +1352,7 @@ fn u256_wide_mul(a: u256, b: u256) -> u512 nopanic { /// Calculates division with remainder of a u512 by a non-zero u256. #[inline(always)] -fn u512_safe_div_rem_by_u256( +pub fn u512_safe_div_rem_by_u256( lhs: u512, rhs: NonZero ) -> (u512, u256) implicits(RangeCheck) nopanic { let (q, r, _, _, _, _, _) = u512_safe_divmod_by_u256(lhs, rhs); @@ -1325,8 +1374,10 @@ extern fn u512_safe_divmod_by_u256( ) implicits(RangeCheck) nopanic; /// Bounded -trait BoundedInt { +pub trait BoundedInt { + #[must_use] fn min() -> T nopanic; + #[must_use] fn max() -> T nopanic; } @@ -1452,62 +1503,62 @@ impl BoundedI128 of BoundedInt { } /// Conversions. -impl Felt252TryIntoU8 of TryInto { +pub(crate) impl Felt252TryIntoU8 of TryInto { fn try_into(self: felt252) -> Option { u8_try_from_felt252(self) } } -impl U8IntoFelt252 of Into { +pub(crate) impl U8IntoFelt252 of Into { fn into(self: u8) -> felt252 { u8_to_felt252(self) } } -impl Felt252TryIntoU16 of TryInto { +pub(crate) impl Felt252TryIntoU16 of TryInto { fn try_into(self: felt252) -> Option { u16_try_from_felt252(self) } } -impl U16IntoFelt252 of Into { +pub(crate) impl U16IntoFelt252 of Into { fn into(self: u16) -> felt252 { u16_to_felt252(self) } } -impl Felt252TryIntoU32 of TryInto { +pub(crate) impl Felt252TryIntoU32 of TryInto { fn try_into(self: felt252) -> Option { u32_try_from_felt252(self) } } -impl U32IntoFelt252 of Into { +pub(crate) impl U32IntoFelt252 of Into { fn into(self: u32) -> felt252 { u32_to_felt252(self) } } -impl Felt252TryIntoU64 of TryInto { +pub(crate) impl Felt252TryIntoU64 of TryInto { fn try_into(self: felt252) -> Option { u64_try_from_felt252(self) } } -impl U64IntoFelt252 of Into { +pub(crate) impl U64IntoFelt252 of Into { fn into(self: u64) -> felt252 { u64_to_felt252(self) } } -impl Felt252TryIntoU128 of TryInto { +pub(crate) impl Felt252TryIntoU128 of TryInto { fn try_into(self: felt252) -> Option { u128_try_from_felt252(self) } } -impl U128IntoFelt252 of Into { +pub(crate) impl U128IntoFelt252 of Into { fn into(self: u128) -> felt252 { u128_to_felt252(self) } } -impl Felt252IntoU256 of Into { +pub(crate) impl Felt252IntoU256 of Into { fn into(self: felt252) -> u256 { u256_from_felt252(self) } } -impl U256TryIntoFelt252 of TryInto { +pub(crate) impl U256TryIntoFelt252 of TryInto { fn try_into(self: u256) -> Option { let FELT252_PRIME_HIGH = 0x8000000000000110000000000000000_u128; if self.high > FELT252_PRIME_HIGH { @@ -1529,7 +1580,7 @@ impl Felt252TryIntoI8 of TryInto { i8_try_from_felt252(self) } } -impl I8IntoFelt252 of Into { +pub(crate) impl I8IntoFelt252 of Into { fn into(self: i8) -> felt252 { i8_to_felt252(self) } @@ -1539,7 +1590,7 @@ impl Felt252TryIntoI16 of TryInto { i16_try_from_felt252(self) } } -impl I16IntoFelt252 of Into { +pub(crate) impl I16IntoFelt252 of Into { fn into(self: i16) -> felt252 { i16_to_felt252(self) } @@ -1549,7 +1600,7 @@ impl Felt252TryIntoI32 of TryInto { i32_try_from_felt252(self) } } -impl I32IntoFelt252 of Into { +pub(crate) impl I32IntoFelt252 of Into { fn into(self: i32) -> felt252 { i32_to_felt252(self) } @@ -1559,7 +1610,7 @@ impl Felt252TryIntoI64 of TryInto { i64_try_from_felt252(self) } } -impl I64IntoFelt252 of Into { +pub(crate) impl I64IntoFelt252 of Into { fn into(self: i64) -> felt252 { i64_to_felt252(self) } @@ -1569,7 +1620,7 @@ impl Felt252TryIntoI128 of TryInto { i128_try_from_felt252(self) } } -impl I128IntoFelt252 of Into { +pub(crate) impl I128IntoFelt252 of Into { fn into(self: i128) -> felt252 { i128_to_felt252(self) } @@ -1577,7 +1628,7 @@ impl I128IntoFelt252 of Into { // TODO(lior): Restrict the function (using traits) in the high-level compiler so that wrong types // will not lead to Sierra errors. -extern fn upcast(x: FromType) -> ToType nopanic; +pub(crate) extern fn upcast(x: FromType) -> ToType nopanic; // TODO(lior): Restrict the function (using traits) in the high-level compiler so that wrong types // will not lead to Sierra errors. @@ -1586,32 +1637,50 @@ extern fn downcast(x: FromType) -> Option implicits(Ra // Marks `FromType` as upcastable to `ToType`. // Do not add user code implementing this trait. trait Upcastable; -impl UpcastableU8U16 of Upcastable {} -impl UpcastableU8U32 of Upcastable {} -impl UpcastableU8U64 of Upcastable {} -impl UpcastableU8U128 of Upcastable {} -impl UpcastableU16U32 of Upcastable {} -impl UpcastableU16U64 of Upcastable {} -impl UpcastableU16U128 of Upcastable {} -impl UpcastableU32U64 of Upcastable {} -impl UpcastableU32U128 of Upcastable {} -impl UpcastableU64U128 of Upcastable {} -// Marks `FromType` as downcastable to `ToType`. +impl UpcastableU8U16 of Upcastable; +impl UpcastableU8I16 of Upcastable; +impl UpcastableU8U32 of Upcastable; +impl UpcastableU8I32 of Upcastable; +impl UpcastableU8U64 of Upcastable; +impl UpcastableU8I64 of Upcastable; +impl UpcastableU8U128 of Upcastable; +impl UpcastableU8I128 of Upcastable; +impl UpcastableI8I16 of Upcastable; +impl UpcastableI8I32 of Upcastable; +impl UpcastableI8I64 of Upcastable; +impl UpcastableI8I128 of Upcastable; +impl UpcastableU16U32 of Upcastable; +impl UpcastableU16I32 of Upcastable; +impl UpcastableU16U64 of Upcastable; +impl UpcastableU16I64 of Upcastable; +impl UpcastableU16U128 of Upcastable; +impl UpcastableU16I128 of Upcastable; +impl UpcastableI16I32 of Upcastable; +impl UpcastableI16I64 of Upcastable; +impl UpcastableI16I128 of Upcastable; +impl UpcastableU32U64 of Upcastable; +impl UpcastableU32I64 of Upcastable; +impl UpcastableU32U128 of Upcastable; +impl UpcastableU32I128 of Upcastable; +impl UpcastableI32I64 of Upcastable; +impl UpcastableI32I128 of Upcastable; +impl UpcastableU64U128 of Upcastable; +impl UpcastableU64I128 of Upcastable; +impl UpcastableI64I128 of Upcastable; +// Marks a type as an int that is downcastable to other downcastable ints. // Do not add user code implementing this trait. -trait Downcastable; -impl DowncastableU128U64 of Downcastable {} -impl DowncastableU128U32 of Downcastable {} -impl DowncastableU128U16 of Downcastable {} -impl DowncastableU128U8 of Downcastable {} +trait DowncastableInt; +impl DowncastableU8 of DowncastableInt; +impl DowncastableI8 of DowncastableInt; +impl DowncastableU16 of DowncastableInt; +impl DowncastableI16 of DowncastableInt; +impl DowncastableU32 of DowncastableInt; +impl DowncastableI32 of DowncastableInt; +impl DowncastableU64 of DowncastableInt; +impl DowncastableI64 of DowncastableInt; +impl DowncastableU128 of DowncastableInt; +impl DowncastableI128 of DowncastableInt; -impl DowncastableU64U32 of Downcastable {} -impl DowncastableU64U16 of Downcastable {} -impl DowncastableU64U8 of Downcastable {} - -impl DowncastableU32U16 of Downcastable {} -impl DowncastableU32U8 of Downcastable {} - -impl DowncastableU16U8 of Downcastable {} /// Default values impl U8Default of Default { @@ -1699,7 +1768,9 @@ impl UpcastableInto> of Into { } } -impl DowncastableTryInto> of TryInto { +impl DowncastableIntTryInto< + From, To, +DowncastableInt, +DowncastableInt, -Into +> of TryInto { fn try_into(self: From) -> Option { downcast(self) } @@ -1795,92 +1866,6 @@ impl U256TryIntoU128 of TryInto { } } -// === Zeroable === - -impl U8Zeroable of Zeroable { - fn zero() -> u8 { - 0 - } - #[inline(always)] - fn is_zero(self: u8) -> bool { - self == U8Zeroable::zero() - } - #[inline(always)] - fn is_non_zero(self: u8) -> bool { - self != U8Zeroable::zero() - } -} - -impl U16Zeroable of Zeroable { - fn zero() -> u16 { - 0 - } - #[inline(always)] - fn is_zero(self: u16) -> bool { - self == U16Zeroable::zero() - } - #[inline(always)] - fn is_non_zero(self: u16) -> bool { - self != U16Zeroable::zero() - } -} - -impl U32Zeroable of Zeroable { - fn zero() -> u32 { - 0 - } - #[inline(always)] - fn is_zero(self: u32) -> bool { - self == U32Zeroable::zero() - } - #[inline(always)] - fn is_non_zero(self: u32) -> bool { - self != U32Zeroable::zero() - } -} - -impl U64Zeroable of Zeroable { - fn zero() -> u64 { - 0 - } - #[inline(always)] - fn is_zero(self: u64) -> bool { - self == U64Zeroable::zero() - } - #[inline(always)] - fn is_non_zero(self: u64) -> bool { - self != U64Zeroable::zero() - } -} - -impl U128Zeroable of Zeroable { - fn zero() -> u128 { - 0 - } - #[inline(always)] - fn is_zero(self: u128) -> bool { - self == U128Zeroable::zero() - } - #[inline(always)] - fn is_non_zero(self: u128) -> bool { - self != U128Zeroable::zero() - } -} - -impl U256Zeroable of Zeroable { - fn zero() -> u256 { - 0 - } - #[inline(always)] - fn is_zero(self: u256) -> bool { - self == U256Zeroable::zero() - } - #[inline(always)] - fn is_non_zero(self: u256) -> bool { - self != U256Zeroable::zero() - } -} - enum SignedIntegerResult { InRange: T, Underflow: T, @@ -1889,9 +1874,8 @@ enum SignedIntegerResult { impl SignedIntegerResultDrop> of Drop>; #[derive(Copy, Drop)] -extern type i8; +pub extern type i8; impl NumericLiterali8 of NumericLiteral; -extern fn i8_const() -> i8 nopanic; extern fn i8_try_from_felt252(a: felt252) -> Option implicits(RangeCheck) nopanic; extern fn i8_to_felt252(a: i8) -> felt252 nopanic; @@ -1921,8 +1905,8 @@ impl I8Add of Add { fn add(lhs: i8, rhs: i8) -> i8 { match i8_overflowing_add_impl(lhs, rhs) { SignedIntegerResult::InRange(result) => result, - SignedIntegerResult::Underflow(_) => panic_with_felt252('i8_add Underflow'), - SignedIntegerResult::Overflow(_) => panic_with_felt252('i8_add Overflow'), + SignedIntegerResult::Underflow(_) => core::panic_with_felt252('i8_add Underflow'), + SignedIntegerResult::Overflow(_) => core::panic_with_felt252('i8_add Overflow'), } } } @@ -1936,8 +1920,8 @@ impl I8Sub of Sub { fn sub(lhs: i8, rhs: i8) -> i8 { match i8_overflowing_sub_impl(lhs, rhs) { SignedIntegerResult::InRange(result) => result, - SignedIntegerResult::Underflow(_) => panic_with_felt252('i8_sub Underflow'), - SignedIntegerResult::Overflow(_) => panic_with_felt252('i8_sub Overflow'), + SignedIntegerResult::Underflow(_) => core::panic_with_felt252('i8_sub Underflow'), + SignedIntegerResult::Overflow(_) => core::panic_with_felt252('i8_sub Overflow'), } } } @@ -1955,10 +1939,10 @@ impl I8Neg of Neg { } } -extern fn i8_wide_mul(lhs: i8, rhs: i8) -> i16 implicits() nopanic; +pub extern fn i8_wide_mul(lhs: i8, rhs: i8) -> i16 implicits() nopanic; impl I8Mul of Mul { fn mul(lhs: i8, rhs: i8) -> i8 { - i8_try_from_felt252(i16_to_felt252(i8_wide_mul(lhs, rhs))).expect('i8_mul Overflow') + i8_wide_mul(lhs, rhs).try_into().expect('i8_mul Overflow') } } impl I8MulEq of MulEq { @@ -1969,7 +1953,7 @@ impl I8MulEq of MulEq { } /// If `lhs` >= `rhs` returns `Ok(lhs - rhs)` else returns `Err(2**8 + lhs - rhs)`. -extern fn i8_diff(lhs: i8, rhs: i8) -> Result implicits(RangeCheck) nopanic; +pub extern fn i8_diff(lhs: i8, rhs: i8) -> Result implicits(RangeCheck) nopanic; impl I8PartialOrd of PartialOrd { #[inline(always)] fn le(lhs: i8, rhs: i8) -> bool { @@ -1989,10 +1973,15 @@ impl I8PartialOrd of PartialOrd { } } +impl I8BitSize of core::num::traits::BitSize { + fn bits() -> usize { + 8 + } +} + #[derive(Copy, Drop)] -extern type i16; +pub extern type i16; impl NumericLiterali16 of NumericLiteral; -extern fn i16_const() -> i16 nopanic; extern fn i16_try_from_felt252(a: felt252) -> Option implicits(RangeCheck) nopanic; extern fn i16_to_felt252(a: i16) -> felt252 nopanic; @@ -2022,8 +2011,8 @@ impl I16Add of Add { fn add(lhs: i16, rhs: i16) -> i16 { match i16_overflowing_add_impl(lhs, rhs) { SignedIntegerResult::InRange(result) => result, - SignedIntegerResult::Underflow(_) => panic_with_felt252('i16_add Underflow'), - SignedIntegerResult::Overflow(_) => panic_with_felt252('i16_add Overflow'), + SignedIntegerResult::Underflow(_) => core::panic_with_felt252('i16_add Underflow'), + SignedIntegerResult::Overflow(_) => core::panic_with_felt252('i16_add Overflow'), } } } @@ -2037,8 +2026,8 @@ impl I16Sub of Sub { fn sub(lhs: i16, rhs: i16) -> i16 { match i16_overflowing_sub_impl(lhs, rhs) { SignedIntegerResult::InRange(result) => result, - SignedIntegerResult::Underflow(_) => panic_with_felt252('i16_sub Underflow'), - SignedIntegerResult::Overflow(_) => panic_with_felt252('i16_sub Overflow'), + SignedIntegerResult::Underflow(_) => core::panic_with_felt252('i16_sub Underflow'), + SignedIntegerResult::Overflow(_) => core::panic_with_felt252('i16_sub Overflow'), } } } @@ -2056,10 +2045,10 @@ impl I16Neg of Neg { } } -extern fn i16_wide_mul(lhs: i16, rhs: i16) -> i32 implicits() nopanic; +pub extern fn i16_wide_mul(lhs: i16, rhs: i16) -> i32 implicits() nopanic; impl I16Mul of Mul { fn mul(lhs: i16, rhs: i16) -> i16 { - i16_try_from_felt252(i32_to_felt252(i16_wide_mul(lhs, rhs))).expect('i16_mul Overflow') + i16_wide_mul(lhs, rhs).try_into().expect('i16_mul Overflow') } } impl I16MulEq of MulEq { @@ -2070,7 +2059,7 @@ impl I16MulEq of MulEq { } /// If `lhs` >= `rhs` returns `Ok(lhs - rhs)` else returns `Err(2**16 + lhs - rhs)`. -extern fn i16_diff(lhs: i16, rhs: i16) -> Result implicits(RangeCheck) nopanic; +pub extern fn i16_diff(lhs: i16, rhs: i16) -> Result implicits(RangeCheck) nopanic; impl I16PartialOrd of PartialOrd { #[inline(always)] fn le(lhs: i16, rhs: i16) -> bool { @@ -2090,10 +2079,15 @@ impl I16PartialOrd of PartialOrd { } } +impl I16BitSize of core::num::traits::BitSize { + fn bits() -> usize { + 16 + } +} + #[derive(Copy, Drop)] -extern type i32; +pub extern type i32; impl NumericLiterali32 of NumericLiteral; -extern fn i32_const() -> i32 nopanic; extern fn i32_try_from_felt252(a: felt252) -> Option implicits(RangeCheck) nopanic; extern fn i32_to_felt252(a: i32) -> felt252 nopanic; @@ -2123,8 +2117,8 @@ impl I32Add of Add { fn add(lhs: i32, rhs: i32) -> i32 { match i32_overflowing_add_impl(lhs, rhs) { SignedIntegerResult::InRange(result) => result, - SignedIntegerResult::Underflow(_) => panic_with_felt252('i32_add Underflow'), - SignedIntegerResult::Overflow(_) => panic_with_felt252('i32_add Overflow'), + SignedIntegerResult::Underflow(_) => core::panic_with_felt252('i32_add Underflow'), + SignedIntegerResult::Overflow(_) => core::panic_with_felt252('i32_add Overflow'), } } } @@ -2138,8 +2132,8 @@ impl I32Sub of Sub { fn sub(lhs: i32, rhs: i32) -> i32 { match i32_overflowing_sub_impl(lhs, rhs) { SignedIntegerResult::InRange(result) => result, - SignedIntegerResult::Underflow(_) => panic_with_felt252('i32_sub Underflow'), - SignedIntegerResult::Overflow(_) => panic_with_felt252('i32_sub Overflow'), + SignedIntegerResult::Underflow(_) => core::panic_with_felt252('i32_sub Underflow'), + SignedIntegerResult::Overflow(_) => core::panic_with_felt252('i32_sub Overflow'), } } } @@ -2157,10 +2151,10 @@ impl I32Neg of Neg { } } -extern fn i32_wide_mul(lhs: i32, rhs: i32) -> i64 implicits() nopanic; +pub extern fn i32_wide_mul(lhs: i32, rhs: i32) -> i64 implicits() nopanic; impl I32Mul of Mul { fn mul(lhs: i32, rhs: i32) -> i32 { - i32_try_from_felt252(i64_to_felt252(i32_wide_mul(lhs, rhs))).expect('i32_mul Overflow') + i32_wide_mul(lhs, rhs).try_into().expect('i32_mul Overflow') } } impl I32MulEq of MulEq { @@ -2171,7 +2165,7 @@ impl I32MulEq of MulEq { } /// If `lhs` >= `rhs` returns `Ok(lhs - rhs)` else returns `Err(2**32 + lhs - rhs)`. -extern fn i32_diff(lhs: i32, rhs: i32) -> Result implicits(RangeCheck) nopanic; +pub extern fn i32_diff(lhs: i32, rhs: i32) -> Result implicits(RangeCheck) nopanic; impl I32PartialOrd of PartialOrd { #[inline(always)] fn le(lhs: i32, rhs: i32) -> bool { @@ -2191,10 +2185,15 @@ impl I32PartialOrd of PartialOrd { } } +impl I32BitSize of core::num::traits::BitSize { + fn bits() -> usize { + 32 + } +} + #[derive(Copy, Drop)] -extern type i64; +pub extern type i64; impl NumericLiterali64 of NumericLiteral; -extern fn i64_const() -> i64 nopanic; extern fn i64_try_from_felt252(a: felt252) -> Option implicits(RangeCheck) nopanic; extern fn i64_to_felt252(a: i64) -> felt252 nopanic; @@ -2224,8 +2223,8 @@ impl I64Add of Add { fn add(lhs: i64, rhs: i64) -> i64 { match i64_overflowing_add_impl(lhs, rhs) { SignedIntegerResult::InRange(result) => result, - SignedIntegerResult::Underflow(_) => panic_with_felt252('i64_add Underflow'), - SignedIntegerResult::Overflow(_) => panic_with_felt252('i64_add Overflow'), + SignedIntegerResult::Underflow(_) => core::panic_with_felt252('i64_add Underflow'), + SignedIntegerResult::Overflow(_) => core::panic_with_felt252('i64_add Overflow'), } } } @@ -2239,8 +2238,8 @@ impl I64Sub of Sub { fn sub(lhs: i64, rhs: i64) -> i64 { match i64_overflowing_sub_impl(lhs, rhs) { SignedIntegerResult::InRange(result) => result, - SignedIntegerResult::Underflow(_) => panic_with_felt252('i64_sub Underflow'), - SignedIntegerResult::Overflow(_) => panic_with_felt252('i64_sub Overflow'), + SignedIntegerResult::Underflow(_) => core::panic_with_felt252('i64_sub Underflow'), + SignedIntegerResult::Overflow(_) => core::panic_with_felt252('i64_sub Overflow'), } } } @@ -2258,10 +2257,10 @@ impl I64Neg of Neg { } } -extern fn i64_wide_mul(lhs: i64, rhs: i64) -> i128 implicits() nopanic; +pub extern fn i64_wide_mul(lhs: i64, rhs: i64) -> i128 implicits() nopanic; impl I64Mul of Mul { fn mul(lhs: i64, rhs: i64) -> i64 { - i64_try_from_felt252(i128_to_felt252(i64_wide_mul(lhs, rhs))).expect('i64_mul Overflow') + i64_wide_mul(lhs, rhs).try_into().expect('i64_mul Overflow') } } impl I64MulEq of MulEq { @@ -2272,7 +2271,7 @@ impl I64MulEq of MulEq { } /// If `lhs` >= `rhs` returns `Ok(lhs - rhs)` else returns `Err(2**64 + lhs - rhs)`. -extern fn i64_diff(lhs: i64, rhs: i64) -> Result implicits(RangeCheck) nopanic; +pub extern fn i64_diff(lhs: i64, rhs: i64) -> Result implicits(RangeCheck) nopanic; impl I64PartialOrd of PartialOrd { #[inline(always)] fn le(lhs: i64, rhs: i64) -> bool { @@ -2292,10 +2291,15 @@ impl I64PartialOrd of PartialOrd { } } +impl I64BitSize of core::num::traits::BitSize { + fn bits() -> usize { + 64 + } +} + #[derive(Copy, Drop)] -extern type i128; +pub extern type i128; impl NumericLiterali128 of NumericLiteral; -extern fn i128_const() -> i128 nopanic; extern fn i128_try_from_felt252(a: felt252) -> Option implicits(RangeCheck) nopanic; extern fn i128_to_felt252(a: i128) -> felt252 nopanic; @@ -2325,8 +2329,8 @@ impl I128Add of Add { fn add(lhs: i128, rhs: i128) -> i128 { match i128_overflowing_add_impl(lhs, rhs) { SignedIntegerResult::InRange(result) => result, - SignedIntegerResult::Underflow(_) => panic_with_felt252('i128_add Underflow'), - SignedIntegerResult::Overflow(_) => panic_with_felt252('i128_add Overflow'), + SignedIntegerResult::Underflow(_) => core::panic_with_felt252('i128_add Underflow'), + SignedIntegerResult::Overflow(_) => core::panic_with_felt252('i128_add Overflow'), } } } @@ -2340,8 +2344,8 @@ impl I128Sub of Sub { fn sub(lhs: i128, rhs: i128) -> i128 { match i128_overflowing_sub_impl(lhs, rhs) { SignedIntegerResult::InRange(result) => result, - SignedIntegerResult::Underflow(_) => panic_with_felt252('i128_sub Underflow'), - SignedIntegerResult::Overflow(_) => panic_with_felt252('i128_sub Overflow'), + SignedIntegerResult::Underflow(_) => core::panic_with_felt252('i128_sub Underflow'), + SignedIntegerResult::Overflow(_) => core::panic_with_felt252('i128_sub Overflow'), } } } @@ -2386,7 +2390,7 @@ impl I128MulEq of MulEq { } /// If `lhs` >= `rhs` returns `Ok(lhs - rhs)` else returns `Err(2**128 + lhs - rhs)`. -extern fn i128_diff(lhs: i128, rhs: i128) -> Result implicits(RangeCheck) nopanic; +pub extern fn i128_diff(lhs: i128, rhs: i128) -> Result implicits(RangeCheck) nopanic; impl I128PartialOrd of PartialOrd { #[inline(always)] fn le(lhs: i128, rhs: i128) -> bool { @@ -2405,3 +2409,338 @@ impl I128PartialOrd of PartialOrd { i128_diff(rhs, lhs).into_is_err() } } + +// Zeroable impls +pub(crate) impl U8Zeroable = core::zeroable::zero_based::ZeroableImpl; +pub(crate) impl U16Zeroable = core::zeroable::zero_based::ZeroableImpl; +pub(crate) impl U32Zeroable = core::zeroable::zero_based::ZeroableImpl; +pub(crate) impl U64Zeroable = core::zeroable::zero_based::ZeroableImpl; +pub(crate) impl U128Zeroable = core::zeroable::zero_based::ZeroableImpl; +pub(crate) impl U256Zeroable = core::zeroable::zero_based::ZeroableImpl; + +impl I128BitSize of core::num::traits::BitSize { + fn bits() -> usize { + 128 + } +} + +// Zero trait implementations +impl U8Zero of core::num::traits::Zero { + fn zero() -> u8 { + 0 + } + #[inline(always)] + fn is_zero(self: @u8) -> bool { + *self == U8Zero::zero() + } + #[inline(always)] + fn is_non_zero(self: @u8) -> bool { + !self.is_zero() + } +} + +impl U16Zero of core::num::traits::Zero { + fn zero() -> u16 { + 0 + } + #[inline(always)] + fn is_zero(self: @u16) -> bool { + *self == U16Zero::zero() + } + #[inline(always)] + fn is_non_zero(self: @u16) -> bool { + !self.is_zero() + } +} + +impl U32Zero of core::num::traits::Zero { + fn zero() -> u32 { + 0 + } + #[inline(always)] + fn is_zero(self: @u32) -> bool { + *self == U32Zero::zero() + } + #[inline(always)] + fn is_non_zero(self: @u32) -> bool { + !self.is_zero() + } +} + +impl U64Zero of core::num::traits::Zero { + fn zero() -> u64 { + 0 + } + #[inline(always)] + fn is_zero(self: @u64) -> bool { + *self == U64Zero::zero() + } + #[inline(always)] + fn is_non_zero(self: @u64) -> bool { + !self.is_zero() + } +} + +impl U128Zero of core::num::traits::Zero { + fn zero() -> u128 { + 0 + } + #[inline(always)] + fn is_zero(self: @u128) -> bool { + *self == U128Zero::zero() + } + #[inline(always)] + fn is_non_zero(self: @u128) -> bool { + !self.is_zero() + } +} + +impl U256Zero of core::num::traits::Zero { + fn zero() -> u256 { + 0 + } + #[inline(always)] + fn is_zero(self: @u256) -> bool { + *self == U256Zero::zero() + } + #[inline(always)] + fn is_non_zero(self: @u256) -> bool { + !self.is_zero() + } +} + +impl I8Zero of core::num::traits::Zero { + fn zero() -> i8 { + 0 + } + #[inline(always)] + fn is_zero(self: @i8) -> bool { + *self == I8Zero::zero() + } + #[inline(always)] + fn is_non_zero(self: @i8) -> bool { + !self.is_zero() + } +} + +impl I16Zero of core::num::traits::Zero { + fn zero() -> i16 { + 0 + } + #[inline(always)] + fn is_zero(self: @i16) -> bool { + *self == I16Zero::zero() + } + #[inline(always)] + fn is_non_zero(self: @i16) -> bool { + !self.is_zero() + } +} + +impl I32Zero of core::num::traits::Zero { + fn zero() -> i32 { + 0 + } + #[inline(always)] + fn is_zero(self: @i32) -> bool { + *self == I32Zero::zero() + } + #[inline(always)] + fn is_non_zero(self: @i32) -> bool { + !self.is_zero() + } +} + +impl I64Zero of core::num::traits::Zero { + fn zero() -> i64 { + 0 + } + #[inline(always)] + fn is_zero(self: @i64) -> bool { + *self == I64Zero::zero() + } + #[inline(always)] + fn is_non_zero(self: @i64) -> bool { + !self.is_zero() + } +} + +impl I128Zero of core::num::traits::Zero { + fn zero() -> i128 { + 0 + } + #[inline(always)] + fn is_zero(self: @i128) -> bool { + *self == I128Zero::zero() + } + #[inline(always)] + fn is_non_zero(self: @i128) -> bool { + !self.is_zero() + } +} + + +// One trait implementations +impl U8One of core::num::traits::One { + fn one() -> u8 { + 1 + } + #[inline(always)] + fn is_one(self: @u8) -> bool { + *self == U8One::one() + } + #[inline(always)] + fn is_non_one(self: @u8) -> bool { + !self.is_one() + } +} + +impl U16One of core::num::traits::One { + fn one() -> u16 { + 1 + } + #[inline(always)] + fn is_one(self: @u16) -> bool { + *self == U16One::one() + } + #[inline(always)] + fn is_non_one(self: @u16) -> bool { + !self.is_one() + } +} + +impl U32One of core::num::traits::One { + fn one() -> u32 { + 1 + } + #[inline(always)] + fn is_one(self: @u32) -> bool { + *self == U32One::one() + } + #[inline(always)] + fn is_non_one(self: @u32) -> bool { + !self.is_one() + } +} + +impl U64One of core::num::traits::One { + fn one() -> u64 { + 1 + } + #[inline(always)] + fn is_one(self: @u64) -> bool { + *self == U64One::one() + } + #[inline(always)] + fn is_non_one(self: @u64) -> bool { + !self.is_one() + } +} + +impl U128One of core::num::traits::One { + fn one() -> u128 { + 1 + } + #[inline(always)] + fn is_one(self: @u128) -> bool { + *self == U128One::one() + } + #[inline(always)] + fn is_non_one(self: @u128) -> bool { + !self.is_one() + } +} + +impl U256One of core::num::traits::One { + fn one() -> u256 { + 1 + } + #[inline(always)] + fn is_one(self: @u256) -> bool { + *self == U256One::one() + } + #[inline(always)] + fn is_non_one(self: @u256) -> bool { + !self.is_one() + } +} + +impl I8One of core::num::traits::One { + fn one() -> i8 { + 1 + } + + #[inline(always)] + fn is_one(self: @i8) -> bool { + *self == I8One::one() + } + + #[inline(always)] + fn is_non_one(self: @i8) -> bool { + !self.is_one() + } +} + +impl I16One of core::num::traits::One { + fn one() -> i16 { + 1 + } + + #[inline(always)] + fn is_one(self: @i16) -> bool { + *self == I16One::one() + } + + #[inline(always)] + fn is_non_one(self: @i16) -> bool { + !self.is_one() + } +} + +impl I32One of core::num::traits::One { + fn one() -> i32 { + 1 + } + + #[inline(always)] + fn is_one(self: @i32) -> bool { + *self == I32One::one() + } + + #[inline(always)] + fn is_non_one(self: @i32) -> bool { + !self.is_one() + } +} + +impl I64One of core::num::traits::One { + fn one() -> i64 { + 1 + } + + #[inline(always)] + fn is_one(self: @i64) -> bool { + *self == I64One::one() + } + + #[inline(always)] + fn is_non_one(self: @i64) -> bool { + !self.is_one() + } +} + +impl I128One of core::num::traits::One { + fn one() -> i128 { + 1 + } + + #[inline(always)] + fn is_one(self: @i128) -> bool { + *self == I128One::one() + } + + #[inline(always)] + fn is_non_one(self: @i128) -> bool { + !self.is_one() + } +} diff --git a/corelib/src/internal.cairo b/corelib/src/internal.cairo index 49a4ee6a5..8513e7cdd 100644 --- a/corelib/src/internal.cairo +++ b/corelib/src/internal.cairo @@ -1,6 +1,11 @@ -extern fn revoke_ap_tracking() implicits() nopanic; +pub extern fn revoke_ap_tracking() implicits() nopanic; /// Function to enforce that `Implicit` is used by a function calling it. /// Note: This extern function is not mapped to a Sierra function, and all usages of it are removed /// during compilation. -extern fn require_implicit() implicits(Implicit) nopanic; +pub extern fn require_implicit() implicits(Implicit) nopanic; + +extern type index_enum_type; + +extern type BoundedInt; + diff --git a/corelib/src/keccak.cairo b/corelib/src/keccak.cairo index 945439061..3bad2138c 100644 --- a/corelib/src/keccak.cairo +++ b/corelib/src/keccak.cairo @@ -1,7 +1,7 @@ -use array::{Span, ArrayTrait, SpanTrait}; -use integer::TryInto; -use option::OptionTrait; -use starknet::SyscallResultTrait; +use core::array::{Span, ArrayTrait, SpanTrait}; +use core::traits::TryInto; +use core::option::OptionTrait; +use core::starknet::SyscallResultTrait; const KECCAK_FULL_RATE_IN_BYTES: usize = 136; const KECCAK_FULL_RATE_IN_U64S: usize = 17; @@ -13,7 +13,7 @@ fn u128_to_u64(input: u128) -> u64 { } fn u128_split(input: u128) -> (u64, u64) { - let (high, low) = integer::u128_safe_divmod( + let (high, low) = core::integer::u128_safe_divmod( input, 0x10000000000000000_u128.try_into().unwrap() ); @@ -33,7 +33,7 @@ fn keccak_add_u256_le(ref keccak_input: Array::, v: u256) { // Computes the keccak256 of multiple u256 values. // The input values are interpreted as little-endian. // The 32-byte result is represented as a little-endian u256. -fn keccak_u256s_le_inputs(mut input: Span) -> u256 { +pub fn keccak_u256s_le_inputs(mut input: Span) -> u256 { let mut keccak_input: Array:: = Default::default(); loop { @@ -48,10 +48,10 @@ fn keccak_u256s_le_inputs(mut input: Span) -> u256 { } fn keccak_add_u256_be(ref keccak_input: Array::, v: u256) { - let (high, low) = u128_split(integer::u128_byte_reverse(v.high)); + let (high, low) = u128_split(core::integer::u128_byte_reverse(v.high)); keccak_input.append(low); keccak_input.append(high); - let (high, low) = u128_split(integer::u128_byte_reverse(v.low)); + let (high, low) = u128_split(core::integer::u128_byte_reverse(v.low)); keccak_input.append(low); keccak_input.append(high); } @@ -59,7 +59,7 @@ fn keccak_add_u256_be(ref keccak_input: Array::, v: u256) { // Computes the keccak256 of multiple u256 values. // The input values are interpreted as big-endian. // The 32-byte result is represented as a little-endian u256. -fn keccak_u256s_be_inputs(mut input: Span) -> u256 { +pub fn keccak_u256s_be_inputs(mut input: Span) -> u256 { let mut keccak_input: Array:: = Default::default(); loop { @@ -82,7 +82,9 @@ fn keccak_u256s_be_inputs(mut input: Span) -> u256 { // 560229490 == int.from_bytes(b'rld!', 'little') // // Returns the hash as a little endian u256. -fn cairo_keccak(ref input: Array, last_input_word: u64, last_input_num_bytes: usize) -> u256 { +pub fn cairo_keccak( + ref input: Array, last_input_word: u64, last_input_num_bytes: usize +) -> u256 { add_padding(ref input, last_input_word, last_input_num_bytes); starknet::syscalls::keccak_syscall(input.span()).unwrap_syscall() } @@ -92,9 +94,7 @@ fn cairo_keccak(ref input: Array, last_input_word: u64, last_input_num_byte fn add_padding(ref input: Array, last_input_word: u64, last_input_num_bytes: usize) { let words_divisor = KECCAK_FULL_RATE_IN_U64S.try_into().unwrap(); // `last_block_num_full_words` is in range [0, KECCAK_FULL_RATE_IN_U64S - 1] - let (_, last_block_num_full_words) = integer::u32_safe_divmod(input.len(), words_divisor); - // `last_block_num_bytes` is in range [0, KECCAK_FULL_RATE_IN_BYTES - 1] - let last_block_num_bytes = last_block_num_full_words * BYTES_IN_U64_WORD + last_input_num_bytes; + let (_, last_block_num_full_words) = core::integer::u32_safe_divmod(input.len(), words_divisor); // The first word to append would be of the form // 0x1<`last_input_num_bytes` LSB bytes of `last_input_word`>. @@ -119,9 +119,9 @@ fn add_padding(ref input: Array, last_input_word: u64, last_input_num_bytes } else if last_input_num_bytes == 7 { 0x100000000000000 } else { - panic_with_felt252('Keccak last input word >7b') + core::panic_with_felt252('Keccak last input word >7b') }; - let (_, r) = integer::u64_safe_divmod( + let (_, r) = core::integer::u64_safe_divmod( last_input_word, first_padding_byte_part.try_into().unwrap() ); first_padding_byte_part + r diff --git a/corelib/src/lib.cairo b/corelib/src/lib.cairo index c6e274b69..677f93114 100644 --- a/corelib/src/lib.cairo +++ b/corelib/src/lib.cairo @@ -1,4 +1,4 @@ -mod traits; +pub mod traits; use traits::{ Add, AddEq, BitAnd, BitNot, BitOr, BitXor, Copy, Div, DivEq, DivRem, Drop, Mul, MulEq, PartialEq, PartialOrd, Rem, RemEq, Sub, SubEq, TupleSize0Copy, TupleSize0Drop, Not, Neg, Into, @@ -6,10 +6,10 @@ use traits::{ }; use serde::Serde; -type usize = u32; +pub type usize = u32; #[derive(Copy, Drop, Default)] -enum bool { +pub enum bool { #[default] False, True, @@ -18,9 +18,9 @@ enum bool { impl BoolSerde of Serde { fn serialize(self: @bool, ref output: Array) { if *self { - 1 + 1_felt252 } else { - 0 + 0_felt252 }.serialize(ref output); } fn deserialize(ref serialized: Span) -> Option { @@ -69,15 +69,15 @@ impl BoolPartialEq of PartialEq { #[inline(always)] fn eq(lhs: @bool, rhs: @bool) -> bool { match lhs { - bool::False => !*rhs, - bool::True => *rhs, + false => !*rhs, + true => *rhs, } } #[inline(always)] fn ne(lhs: @bool, rhs: @bool) -> bool { match lhs { - bool::False => *rhs, - bool::True => !*rhs, + false => *rhs, + true => !*rhs, } } } @@ -97,14 +97,18 @@ impl BoolIntoFelt252 of Into { bool_to_felt252(self) } } +pub mod boolean; // General purpose implicits. -extern type RangeCheck; -extern type SegmentArena; +pub extern type RangeCheck; +pub extern type SegmentArena; // felt252. +mod felt_252; +use felt_252::{Felt252One, Felt252Zero}; + #[derive(Copy, Drop)] -extern type felt252; +pub extern type felt252; extern fn felt252_const() -> felt252 nopanic; impl Felt252Serde of Serde { @@ -166,7 +170,7 @@ impl Felt252Neg of Neg { } } -extern fn felt252_div(lhs: felt252, rhs: NonZero) -> felt252 nopanic; +pub extern fn felt252_div(lhs: felt252, rhs: NonZero) -> felt252 nopanic; impl Felt252PartialEq of PartialEq { #[inline(always)] @@ -212,134 +216,144 @@ extern fn dup(obj: T) -> (T, T) nopanic; extern fn drop(obj: T) nopanic; // Boxes. -mod box; +pub mod box; use box::{Box, BoxTrait}; // Nullable -mod nullable; +pub mod nullable; use nullable::{Nullable, NullableTrait, match_nullable, null, nullable_from_box}; // Array. -mod array; +pub mod array; use array::{Array, ArrayTrait}; // Span. use array::{Span, SpanTrait}; // Dictionary. -mod dict; +pub mod dict; use dict::{ Felt252Dict, SquashedFelt252Dict, felt252_dict_new, felt252_dict_squash, Felt252DictTrait }; // Result. -mod result; +pub mod result; use result::{Result, ResultTrait}; // Option. -mod option; +pub mod option; use option::{Option, OptionTrait}; // Clone. -mod clone; +pub mod clone; use clone::Clone; // EC. -mod ec; +pub mod ec; use ec::{EcOp, EcPoint, EcState}; -mod ecdsa; +pub mod ecdsa; // Integer. -mod integer; +pub mod integer; use integer::{ - i8, i8_const, I8IntoFelt252, i16, i16_const, I16IntoFelt252, i32, i32_const, I32IntoFelt252, - i64, i64_const, I64IntoFelt252, i128, i128_const, I128IntoFelt252, NumericLiteral, u128, - u128_const, u128_sqrt, u128_is_zero, u8, u8_const, u16, u16_const, u32, u32_const, u64, - u64_const, u256, u256_sqrt, Felt252TryIntoU8, U8IntoFelt252, Felt252TryIntoU16, U16IntoFelt252, + i8, I8IntoFelt252, i16, I16IntoFelt252, i32, I32IntoFelt252, i64, I64IntoFelt252, i128, + I128IntoFelt252, NumericLiteral, u128, u128_sqrt, u128_is_zero, u8, u16, u32, u64, u256, + u256_sqrt, Felt252TryIntoU8, U8IntoFelt252, Felt252TryIntoU16, U16IntoFelt252, Felt252TryIntoU32, U32IntoFelt252, Felt252TryIntoU64, U64IntoFelt252, Felt252TryIntoU128, U128IntoFelt252, Felt252IntoU256, Bitwise }; // Math. -mod math; +pub mod math; + +// Num. +pub mod num; // Cmp. -mod cmp; +pub mod cmp; // Gas. -mod gas; +pub mod gas; use gas::{BuiltinCosts, GasBuiltin, get_builtin_costs}; // Panics. -mod panics; +pub mod panics; use panics::{panic, Panic, PanicResult}; -enum never {} +pub enum never {} #[inline(always)] -fn panic_with_felt252(err_code: felt252) -> never { +pub fn panic_with_felt252(err_code: felt252) -> never { panic(array![err_code]) } #[inline(always)] -fn assert(cond: bool, err_code: felt252) { +pub fn assert(cond: bool, err_code: felt252) { if !cond { panic_with_felt252(err_code) } } // Serialization and Deserialization. -mod serde; +pub mod serde; // Hash functions. -mod hash; +pub mod hash; -mod keccak; +pub mod keccak; // Pedersen -mod pedersen; +pub mod pedersen; use pedersen::Pedersen; // Poseidon -mod poseidon; +pub mod poseidon; use poseidon::Poseidon; // Debug. -mod debug; +pub mod debug; + +pub mod fmt; // Starknet -mod starknet; +pub mod starknet; use starknet::System; // Internals. -mod internal; +pub mod internal; // Zeroable. -mod zeroable; +pub mod zeroable; use zeroable::{Zeroable, NonZero}; // bytes31. -mod bytes_31; +pub mod bytes_31; use bytes_31::{ bytes31, bytes31_const, Bytes31IndexView, Bytes31IntoFelt252, Bytes31Trait, Felt252TryIntoBytes31 }; // BytesArray. -mod byte_array; +pub mod byte_array; use byte_array::{ByteArray, ByteArrayIndexView, ByteArrayStringLiteral, ByteArrayTrait}; // String. -mod string; +pub mod string; use string::StringLiteral; // to_byte_array. -mod to_byte_array; +pub mod to_byte_array; #[cfg(test)] mod test; // Module for testing only. -mod testing; +pub mod testing; + +// Metaprogramming. +pub mod metaprogramming; + +// Preludes. +mod prelude; diff --git a/corelib/src/math.cairo b/corelib/src/math.cairo index fd8027686..e1ea0825c 100644 --- a/corelib/src/math.cairo +++ b/corelib/src/math.cairo @@ -1,7 +1,7 @@ -use zeroable::{IsZeroResult, NonZeroIntoImpl, Zeroable}; -use traits::{Into, TryInto}; -use option::OptionTrait; -use integer::{u256_wide_mul, u512_safe_div_rem_by_u256}; +use core::zeroable::{IsZeroResult, NonZeroIntoImpl, Zeroable}; +use core::traits::{Into, TryInto}; +use core::option::OptionTrait; +use core::integer::{u256_wide_mul, u512_safe_div_rem_by_u256, U128MulGuarantee}; // TODO(yuval): use signed integers once supported. // TODO(yuval): use a single impl of a trait with associated impls, once associated impls are @@ -12,7 +12,7 @@ use integer::{u256_wide_mul, u512_safe_div_rem_by_u256}; /// `(s, -t)` or `(-s, t)` are the Bezout coefficients (according to `sub_direction`). /// /// Uses the Extended Euclidean algorithm. -fn egcd< +pub fn egcd< T, +Copy, +Drop, @@ -42,7 +42,7 @@ fn egcd< // TODO(yuval): use signed integers once supported. /// Returns the inverse of `a` modulo `n`, or None if `gcd(a, n) > 1`. -fn inv_mod< +pub fn inv_mod< T, +Copy, +Drop, @@ -77,13 +77,44 @@ fn inv_mod< } } +/// Returns `1 / b (mod n)`, or None if `b` is not invertible modulo `n`. +/// All `b`s will be considered not invertible for `n == 1`. +/// Additionally returns several `U128MulGuarantee`s that are required for validating the +/// calculation. +extern fn u256_guarantee_inv_mod_n( + b: u256, n: NonZero +) -> Result< + ( + NonZero, + U128MulGuarantee, + U128MulGuarantee, + U128MulGuarantee, + U128MulGuarantee, + U128MulGuarantee, + U128MulGuarantee, + U128MulGuarantee, + U128MulGuarantee + ), + (U128MulGuarantee, U128MulGuarantee) +> implicits(RangeCheck) nopanic; + +/// Returns the inverse of `a` modulo `n`, or None if `a` is not invertible modulo `n`. +/// All `b`s will be considered not invertible for `n == 1`. +#[inline(always)] +pub fn u256_inv_mod(a: u256, n: NonZero) -> Option> { + match u256_guarantee_inv_mod_n(a, n) { + Result::Ok((inv_a, _, _, _, _, _, _, _, _)) => Option::Some(inv_a), + Result::Err(_) => Option::None(()) + } +} + /// Returns `a / b (mod n)`, or None if `b` is not invertible modulo `n`. -fn u256_div_mod_n(a: u256, b: NonZero, n: NonZero) -> Option { - Option::Some(u256_mul_mod_n(a, inv_mod(b, n)?, n)) +pub fn u256_div_mod_n(a: u256, b: u256, n: NonZero) -> Option { + Option::Some(u256_mul_mod_n(a, u256_inv_mod(b, n)?.into(), n)) } /// Returns `a * b (mod n)`. -fn u256_mul_mod_n(a: u256, b: u256, n: NonZero) -> u256 { +pub fn u256_mul_mod_n(a: u256, b: u256, n: NonZero) -> u256 { let (_, r) = u512_safe_div_rem_by_u256(u256_wide_mul(a, b), n); r } @@ -92,93 +123,38 @@ fn u256_mul_mod_n(a: u256, b: u256, n: NonZero) -> u256 { trait Oneable { /// Returns the multiplicative identity element of Self, 1. + #[must_use] fn one() -> T; /// Returns whether self is equal to 1, the multiplicative identity element. + #[must_use] fn is_one(self: T) -> bool; /// Returns whether self is not equal to 1, the multiplicative identity element. + #[must_use] fn is_non_one(self: T) -> bool; } -impl U8Oneable of Oneable { - fn one() -> u8 { - 1 - } - #[inline(always)] - fn is_one(self: u8) -> bool { - self == U8Oneable::one() - } - #[inline(always)] - fn is_non_one(self: u8) -> bool { - self != U8Oneable::one() - } -} - -impl U16Oneable of Oneable { - fn one() -> u16 { - 1 - } - #[inline(always)] - fn is_one(self: u16) -> bool { - self == U16Oneable::one() - } - #[inline(always)] - fn is_non_one(self: u16) -> bool { - self != U16Oneable::one() - } -} - -impl U32Oneable of Oneable { - fn one() -> u32 { - 1 - } - #[inline(always)] - fn is_one(self: u32) -> bool { - self == U32Oneable::one() - } - #[inline(always)] - fn is_non_one(self: u32) -> bool { - self != U32Oneable::one() - } -} - -impl U64Oneable of Oneable { - fn one() -> u64 { - 1 - } - #[inline(always)] - fn is_one(self: u64) -> bool { - self == U64Oneable::one() - } - #[inline(always)] - fn is_non_one(self: u64) -> bool { - self != U64Oneable::one() - } -} - -impl U128Oneable of Oneable { - fn one() -> u128 { - 1 - } - #[inline(always)] - fn is_one(self: u128) -> bool { - self == U128Oneable::one() - } - #[inline(always)] - fn is_non_one(self: u128) -> bool { - self != U128Oneable::one() +pub(crate) mod one_based { + pub(crate) impl OneableImpl< + T, impl OneImpl: core::num::traits::One, +Drop, +Copy + > of super::Oneable { + fn one() -> T { + OneImpl::one() + } + #[inline(always)] + fn is_one(self: T) -> bool { + OneImpl::is_one(@self) + } + #[inline(always)] + fn is_non_one(self: T) -> bool { + OneImpl::is_non_one(@self) + } } } -impl U256Oneable of Oneable { - fn one() -> u256 { - 1 - } - #[inline(always)] - fn is_one(self: u256) -> bool { - self == U256Oneable::one() - } - #[inline(always)] - fn is_non_one(self: u256) -> bool { - self != U256Oneable::one() - } -} +// Oneable impls +impl U8Oneable = math::one_based::OneableImpl; +impl U16Oneable = math::one_based::OneableImpl; +impl U32Oneable = math::one_based::OneableImpl; +impl U64Oneable = math::one_based::OneableImpl; +impl U128Oneable = math::one_based::OneableImpl; +impl U256Oneable = math::one_based::OneableImpl; diff --git a/corelib/src/metaprogramming.cairo b/corelib/src/metaprogramming.cairo new file mode 100644 index 000000000..87ed62e9d --- /dev/null +++ b/corelib/src/metaprogramming.cairo @@ -0,0 +1,5 @@ +/// A trait that can be used to disable implementations based on the types of the generic args. +/// Assumes that `TypeEqualImpl` is the only implementation of this trait. +pub trait TypeEqual {} + +impl TypeEqualImpl of TypeEqual; diff --git a/corelib/src/nullable.cairo b/corelib/src/nullable.cairo index a7a35fd22..5f2c37ba5 100644 --- a/corelib/src/nullable.cairo +++ b/corelib/src/nullable.cairo @@ -1,38 +1,53 @@ -use box::BoxTrait; -use traits::Default; -use traits::Felt252DictValue; +use core::box::BoxTrait; +use core::traits::Default; +use core::traits::Felt252DictValue; #[derive(Copy, Drop)] -extern type Nullable; +pub extern type Nullable; -enum FromNullableResult { +pub enum FromNullableResult { Null, NotNull: Box, } -extern fn null() -> Nullable nopanic; -extern fn nullable_from_box(value: Box) -> Nullable nopanic; -extern fn match_nullable(value: Nullable) -> FromNullableResult nopanic; +pub extern fn null() -> Nullable nopanic; +pub(crate) extern fn nullable_from_box(value: Box) -> Nullable nopanic; +pub extern fn match_nullable(value: Nullable) -> FromNullableResult nopanic; +extern fn nullable_forward_snapshot(value: @Nullable) -> Nullable<@T> nopanic; -trait NullableTrait { - fn deref(self: Nullable) -> T; - fn new(value: T) -> Nullable; -} - -impl NullableImpl of NullableTrait { +#[generate_trait] +pub impl NullableImpl of NullableTrait { fn deref(self: Nullable) -> T { match match_nullable(self) { - FromNullableResult::Null => panic_with_felt252('Attempted to deref null value'), + FromNullableResult::Null => core::panic_with_felt252('Attempted to deref null value'), FromNullableResult::NotNull(value) => value.unbox(), } } + fn deref_or<+Drop>(self: Nullable, default: T) -> T { + match match_nullable(self) { + FromNullableResult::Null => default, + FromNullableResult::NotNull(value) => value.unbox(), + } + } + #[must_use] fn new(value: T) -> Nullable { nullable_from_box(BoxTrait::new(value)) } + #[must_use] + fn is_null(self: @Nullable) -> bool { + match match_nullable(self.as_snapshot()) { + FromNullableResult::Null => true, + FromNullableResult::NotNull(_) => false, + } + } + fn as_snapshot(self: @Nullable) -> Nullable<@T> nopanic { + nullable_forward_snapshot(self) + } } impl NullableDefault of Default> { #[inline(always)] + #[must_use] fn default() -> Nullable nopanic { null() } @@ -40,7 +55,20 @@ impl NullableDefault of Default> { impl NullableFelt252DictValue of Felt252DictValue> { #[inline(always)] + #[must_use] fn zero_default() -> Nullable nopanic { null() } } + +impl NullableDebug> of core::fmt::Debug> { + fn fmt(self: @Nullable, ref f: core::fmt::Formatter) -> Result<(), core::fmt::Error> { + match match_nullable(self.as_snapshot()) { + FromNullableResult::Null => write!(f, "null"), + FromNullableResult::NotNull(value) => { + write!(f, "&")?; + TDebug::fmt(value.unbox(), ref f) + }, + } + } +} diff --git a/corelib/src/num.cairo b/corelib/src/num.cairo new file mode 100644 index 000000000..f6ac8fc7b --- /dev/null +++ b/corelib/src/num.cairo @@ -0,0 +1 @@ +pub mod traits; diff --git a/corelib/src/num/traits.cairo b/corelib/src/num/traits.cairo new file mode 100644 index 000000000..75f57a4e3 --- /dev/null +++ b/corelib/src/num/traits.cairo @@ -0,0 +1,8 @@ +pub mod zero; +pub use zero::Zero; + +pub mod one; +pub use one::One; + +pub mod bit_size; +pub use bit_size::BitSize; diff --git a/corelib/src/num/traits/bit_size.cairo b/corelib/src/num/traits/bit_size.cairo new file mode 100644 index 000000000..76d50a40b --- /dev/null +++ b/corelib/src/num/traits/bit_size.cairo @@ -0,0 +1,6 @@ +/// Trait used to retrieve the size in bits of a type. +pub trait BitSize { + /// Returns the size in bits of T as usize. + #[must_use] + fn bits() -> usize; +} diff --git a/corelib/src/num/traits/one.cairo b/corelib/src/num/traits/one.cairo new file mode 100644 index 000000000..34ff7a0b2 --- /dev/null +++ b/corelib/src/num/traits/one.cairo @@ -0,0 +1,9 @@ +/// Defines a multiplicative identity element for `T`. +pub trait One { + /// Returns the multiplicative identity element of `T`, `1`. + fn one() -> T; + /// Returns `true` if `self` is equal to the multiplicative identity. + fn is_one(self: @T) -> bool; + /// Returns `false` if `self` is equal to the multiplicative identity. + fn is_non_one(self: @T) -> bool; +} diff --git a/corelib/src/num/traits/zero.cairo b/corelib/src/num/traits/zero.cairo new file mode 100644 index 000000000..c43bd5d30 --- /dev/null +++ b/corelib/src/num/traits/zero.cairo @@ -0,0 +1,9 @@ +/// Defines an additive identity element for `T`. +pub trait Zero { + /// Returns the additive identity element of `T`, `0`. + fn zero() -> T; + /// Returns `true` if `self` is equal to the additive identity. + fn is_zero(self: @T) -> bool; + /// Returns `false` if `self` is equal to the additive identity. + fn is_non_zero(self: @T) -> bool; +} diff --git a/corelib/src/option.cairo b/corelib/src/option.cairo index 31c3148db..6db7b302b 100644 --- a/corelib/src/option.cairo +++ b/corelib/src/option.cairo @@ -1,14 +1,21 @@ -use array::ArrayTrait; -use serde::Serde; -use array::SpanTrait; - -#[derive(Copy, Drop, Serde, PartialEq)] -enum Option { +#[must_use] +#[derive(Copy, Drop, Debug, Serde, PartialEq)] +pub enum Option { Some: T, None, } -trait OptionTrait { +pub impl DestructOption, -Drop>> of Destruct> { + #[inline(always)] + fn destruct(self: Option) nopanic { + match self { + Option::Some(x) => x.destruct(), + Option::None => (), + }; + } +} + +pub trait OptionTrait { /// If `val` is `Option::Some(x)`, returns `x`. Otherwise, panics with `err`. fn expect(self: Option, err: felt252) -> T; /// If `val` is `Option::Some(x)`, returns `x`. Otherwise, panics. @@ -17,16 +24,23 @@ trait OptionTrait { /// `Result::Ok(v)` and `Option::None` to `Result::Err(err)`. fn ok_or>(self: Option, err: E) -> Result; /// Returns `true` if the `Option` is `Option::Some`. + #[must_use] fn is_some(self: @Option) -> bool; /// Returns `true` if the `Option` is `Option::None`. + #[must_use] fn is_none(self: @Option) -> bool; + /// If `self` is `Option::Some(x)`, returns `x`. Otherwise, returns the provided default. + fn unwrap_or<+Drop>(self: Option, default: T) -> T; + /// If `self` is `Option::Some(x)`, returns `x`. Otherwise, returns `Default::::default()`. + fn unwrap_or_default<+Default>(self: Option) -> T; } -impl OptionTraitImpl of OptionTrait { + +pub impl OptionTraitImpl of OptionTrait { #[inline(always)] fn expect(self: Option, err: felt252) -> T { match self { Option::Some(x) => x, - Option::None => panic_with_felt252(err), + Option::None => core::panic_with_felt252(err), } } @@ -58,4 +72,20 @@ impl OptionTraitImpl of OptionTrait { Option::None => true, } } + + #[inline] + fn unwrap_or<+Drop>(self: Option, default: T) -> T { + match self { + Option::Some(x) => x, + Option::None => default, + } + } + + #[inline] + fn unwrap_or_default<+Default>(self: Option) -> T { + match self { + Option::Some(x) => x, + Option::None => Default::default(), + } + } } diff --git a/corelib/src/panics.cairo b/corelib/src/panics.cairo index 1541a81ec..c6b49cc6e 100644 --- a/corelib/src/panics.cairo +++ b/corelib/src/panics.cairo @@ -1,10 +1,19 @@ -use array::Array; +use core::array::Array; -struct Panic {} +pub struct Panic {} -enum PanicResult { +pub enum PanicResult { Ok: T, Err: (Panic, Array), } -extern fn panic(data: Array) -> never; +pub extern fn panic(data: Array) -> core::never; + +/// Panics with the given ByteArray. That is, panics with an `Array` with +/// `BYTE_ARRAY_MAGIC`, and then the serialized given ByteArray. +#[inline(always)] +pub fn panic_with_byte_array(err: @ByteArray) -> core::never { + let mut serialized = array![core::byte_array::BYTE_ARRAY_MAGIC]; + err.serialize(ref serialized); + panic(serialized) +} diff --git a/corelib/src/pedersen.cairo b/corelib/src/pedersen.cairo index 11f912900..8a5bf72a5 100644 --- a/corelib/src/pedersen.cairo +++ b/corelib/src/pedersen.cairo @@ -1,16 +1,16 @@ -extern type Pedersen; +pub extern type Pedersen; -extern fn pedersen(a: felt252, b: felt252) -> felt252 implicits(Pedersen) nopanic; +pub extern fn pedersen(a: felt252, b: felt252) -> felt252 implicits(Pedersen) nopanic; /// State for Pedersen hash. -#[derive(Copy, Drop)] -struct HashState { - state: felt252, +#[derive(Copy, Drop, Debug)] +pub struct HashState { + pub state: felt252, } #[generate_trait] -impl PedersenImpl of PedersenTrait { +pub impl PedersenImpl of PedersenTrait { /// Creates a state from a base value. #[inline(always)] fn new(base: felt252) -> HashState { @@ -18,7 +18,7 @@ impl PedersenImpl of PedersenTrait { } } -impl HashStateImpl of hash::HashStateTrait { +impl HashStateImpl of core::hash::HashStateTrait { #[inline(always)] fn update(self: HashState, value: felt252) -> HashState { HashState { state: pedersen(self.state, value) } diff --git a/corelib/src/poseidon.cairo b/corelib/src/poseidon.cairo index c935425c0..9540160e2 100644 --- a/corelib/src/poseidon.cairo +++ b/corelib/src/poseidon.cairo @@ -1,25 +1,25 @@ -use array::Span; -use array::SpanTrait; -use option::OptionTrait; -use hash::HashStateTrait; +use core::array::Span; +use core::array::SpanTrait; +use core::option::OptionTrait; +use core::hash::HashStateTrait; -extern type Poseidon; +pub extern type Poseidon; -extern fn hades_permutation( +pub extern fn hades_permutation( s0: felt252, s1: felt252, s2: felt252 ) -> (felt252, felt252, felt252) implicits(Poseidon) nopanic; /// State for Poseidon hash. -#[derive(Copy, Drop)] -struct HashState { - s0: felt252, - s1: felt252, - s2: felt252, - odd: bool, +#[derive(Copy, Drop, Debug)] +pub struct HashState { + pub s0: felt252, + pub s1: felt252, + pub s2: felt252, + pub odd: bool, } #[generate_trait] -impl PoseidonImpl of PoseidonTrait { +pub impl PoseidonImpl of PoseidonTrait { /// Creates an initial state. #[inline(always)] fn new() -> HashState { @@ -62,13 +62,15 @@ impl HashStateImpl of HashStateTrait { /// 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 { - _poseidon_hash_span_inner(get_builtin_costs(), (0, 0, 0), ref span) +pub fn poseidon_hash_span(mut span: Span) -> felt252 { + _poseidon_hash_span_inner(core::gas::get_builtin_costs(), (0, 0, 0), ref span) } /// Helper function for poseidon_hash_span. fn _poseidon_hash_span_inner( - builtin_costs: gas::BuiltinCosts, state: (felt252, felt252, felt252), ref span: Span + builtin_costs: core::gas::BuiltinCosts, + state: (felt252, felt252, felt252), + ref span: Span ) -> felt252 { let (s0, s1, s2) = state; let x = *match span.pop_front() { @@ -80,6 +82,6 @@ fn _poseidon_hash_span_inner( Option::None => { return HashState { s0: s0 + x, s1, s2, odd: true }.finalize(); }, }; let next_state = hades_permutation(s0 + x, s1 + y, s2); - gas::withdraw_gas_all(builtin_costs).expect('Out of gas'); + core::gas::withdraw_gas_all(builtin_costs).expect('Out of gas'); _poseidon_hash_span_inner(builtin_costs, next_state, ref span) } diff --git a/corelib/src/prelude.cairo b/corelib/src/prelude.cairo new file mode 100644 index 000000000..c82d9325e --- /dev/null +++ b/corelib/src/prelude.cairo @@ -0,0 +1,2 @@ +mod v2023_01; +mod v2023_10; diff --git a/corelib/src/prelude/v2023_01.cairo b/corelib/src/prelude/v2023_01.cairo new file mode 100644 index 000000000..d2bf4f23e --- /dev/null +++ b/corelib/src/prelude/v2023_01.cairo @@ -0,0 +1,70 @@ +use core::{ + BoolBitAnd, BoolBitOr, BoolBitXor, BoolFelt252DictValue, BoolIntoFelt252, BoolNot, + BoolPartialEq, BoolSerde, Felt252Add, Felt252AddEq, Felt252Default, Felt252Felt252DictValue, + Felt252Mul, Felt252MulEq, Felt252Neg, Felt252PartialEq, Felt252Serde, Felt252Sub, Felt252SubEq, + Felt252TryIntoNonZero, RangeCheck, SegmentArena, assert, bool, bool_and_impl, bool_not_impl, + bool_or_impl, bool_to_felt252, bool_xor_impl, drop, dup, felt252, felt252_add, felt252_const, + felt252_div, felt252_is_zero, felt252_mul, felt252_sub, never, panic_with_felt252, usize +}; + +use core::{array, array::{Array, ArrayTrait, Span, SpanTrait}}; +use core::{box, box::{Box, BoxTrait}}; +use core::{ + bytes_31, + bytes_31::{ + Bytes31IndexView, Bytes31IntoFelt252, Bytes31Trait, Felt252TryIntoBytes31, bytes31, + bytes31_const + } +}; +use core::{ + byte_array, byte_array::{ByteArray, ByteArrayIndexView, ByteArrayStringLiteral, ByteArrayTrait} +}; +use core::{clone, clone::Clone}; +use core::cmp; +use core::debug; +use core::{ + dict, + dict::{ + Felt252Dict, Felt252DictTrait, SquashedFelt252Dict, felt252_dict_new, felt252_dict_squash + } +}; +use core::{ec, ec::{EcOp, EcPoint, EcState}}; +use core::ecdsa; +use core::{gas, gas::{BuiltinCosts, GasBuiltin, get_builtin_costs}}; +use core::hash; +use core::{ + integer, + integer::{ + Bitwise, Felt252IntoU256, Felt252TryIntoU128, Felt252TryIntoU16, Felt252TryIntoU32, + Felt252TryIntoU64, Felt252TryIntoU8, I128IntoFelt252, I16IntoFelt252, I32IntoFelt252, + I64IntoFelt252, I8IntoFelt252, NumericLiteral, U128IntoFelt252, U16IntoFelt252, + U32IntoFelt252, U64IntoFelt252, U8IntoFelt252, i128, i16, i32, i64, i8, u128, u128_is_zero, + u128_sqrt, u16, u256, u256_sqrt, u32, u64, u8 + } +}; +use core::internal; +use core::keccak; +use core::math; +use core::{nullable, nullable::{Nullable, NullableTrait, match_nullable, null, nullable_from_box}}; +use core::{option, option::{Option, OptionTrait}}; +use core::{panics, panics::{Panic, PanicResult, panic}}; +use core::{pedersen, pedersen::Pedersen}; +use core::{poseidon, poseidon::Poseidon}; +use core::{result, result::{Result, ResultTrait}}; +use core::{serde, serde::Serde}; +use core::{starknet, starknet::System}; +use core::{string, string::StringLiteral}; +use core::testing; +use core::to_byte_array; +use core::{ + traits, + traits::{ + Add, AddEq, BitAnd, BitNot, BitOr, BitXor, Copy, Default, Destruct, Div, DivEq, DivRem, + Drop, Felt252DictValue, Index, IndexView, Into, Mul, MulEq, Neg, Not, PanicDestruct, + PartialEq, PartialOrd, Rem, RemEq, Sub, SubEq, TryInto, TupleSize0Copy, TupleSize0Drop + } +}; +use core::{zeroable, zeroable::{NonZero, Zeroable}}; + +#[cfg(test)] +use core::test; diff --git a/corelib/src/prelude/v2023_10.cairo b/corelib/src/prelude/v2023_10.cairo new file mode 100644 index 000000000..61e714dcd --- /dev/null +++ b/corelib/src/prelude/v2023_10.cairo @@ -0,0 +1,27 @@ +pub use core::{RangeCheck, SegmentArena, assert, bool, felt252, usize}; + +pub use core::array::{Array, ArrayTrait, Span, SpanTrait}; +pub use core::box::{Box, BoxTrait}; +pub use core::bytes_31::{Bytes31Trait, bytes31}; +pub use core::byte_array::{ByteArray, ByteArrayTrait}; +pub use core::clone::Clone; +pub use core::dict::{Felt252Dict, Felt252DictTrait, SquashedFelt252Dict}; +pub use core::gas::GasBuiltin; +pub use core::integer::{Bitwise, i128, i16, i32, i64, i8, u128, u16, u256, u32, u64, u8}; +pub use core::keccak; +pub use core::math; +pub use core::nullable::{Nullable, NullableTrait}; +pub use core::option::{Option, OptionTrait}; +pub use core::panics::{Panic, PanicResult, panic}; +pub use core::pedersen::Pedersen; +pub use core::poseidon::Poseidon; +pub use core::result::{Result, ResultTrait}; +pub use core::serde::Serde; +pub use core::{starknet, starknet::System}; +pub use core::to_byte_array; +pub use core::traits::{ + Add, AddEq, BitAnd, BitNot, BitOr, BitXor, Copy, Default, Destruct, Div, DivEq, DivRem, Drop, + Felt252DictValue, Index, IndexView, Into, Mul, MulEq, Neg, Not, PanicDestruct, PartialEq, + PartialOrd, Rem, RemEq, Sub, SubEq, TryInto +}; +pub use core::zeroable::NonZero; diff --git a/corelib/src/result.cairo b/corelib/src/result.cairo index bc9535bee..b9eb9aa22 100644 --- a/corelib/src/result.cairo +++ b/corelib/src/result.cairo @@ -1,30 +1,47 @@ -use array::ArrayTrait; -use serde::Serde; -use array::SpanTrait; +use core::array::ArrayTrait; +use core::serde::Serde; +use core::array::SpanTrait; -#[derive(Copy, Drop, Serde, PartialEq)] -enum Result { +#[must_use] +#[derive(Copy, Drop, Debug, Serde, PartialEq)] +pub enum Result { Ok: T, Err: E, } #[generate_trait] -impl ResultTraitImpl of ResultTrait { +pub impl ResultTraitImpl of ResultTrait { /// If `val` is `Result::Ok(x)`, returns `x`. Otherwise, panics with `err`. fn expect<+Drop>(self: Result, err: felt252) -> T { match self { Result::Ok(x) => x, - Result::Err(_) => panic_with_felt252(err), + Result::Err(_) => core::panic_with_felt252(err), } } /// If `val` is `Result::Ok(x)`, returns `x`. Otherwise, panics. fn unwrap<+Drop>(self: Result) -> T { self.expect('Result::unwrap failed.') } + /// If `val` is `Result::Ok(x)`, returns `x`. Otherwise, returns `default`. + fn unwrap_or<+Drop, +Drop>(self: Result, default: T) -> T { + match self { + Result::Ok(x) => x, + Result::Err(_) => default, + } + } + /// If `val` is `Result::Ok(x)`, returns `x`. + /// Otherwise returns `Default::::default()`. + fn unwrap_or_default<+Drop, +Default>(self: Result) -> T { + match self { + Result::Ok(x) => x, + Result::Err(_) => Default::default(), + } + } + /// If `val` is `Result::Err(x)`, returns `x`. Otherwise, panics with `err`. fn expect_err<+Drop>(self: Result, err: felt252) -> E { match self { - Result::Ok(_) => panic_with_felt252(err), + Result::Ok(_) => core::panic_with_felt252(err), Result::Err(x) => x, } } diff --git a/corelib/src/serde.cairo b/corelib/src/serde.cairo index b4e2cef79..98b0419dd 100644 --- a/corelib/src/serde.cairo +++ b/corelib/src/serde.cairo @@ -1,7 +1,7 @@ -use array::ArrayTrait; -use array::SpanTrait; +use core::array::ArrayTrait; +use core::array::SpanTrait; -trait Serde { +pub trait Serde { fn serialize(self: @T, ref output: Array); fn deserialize(ref serialized: Span) -> Option; } @@ -92,10 +92,10 @@ impl TupleSize4Serde< /// ```ignore /// impl MyTypeSerde = core::serde::into_felt252_based::SerdeImpl;` /// ``` -mod into_felt252_based { - use traits::{Into, TryInto}; +pub mod into_felt252_based { + use core::traits::{Into, TryInto}; use core::array::ArrayTrait; - impl SerdeImpl, +Into, +TryInto> of super::Serde { + pub impl SerdeImpl, +Into, +TryInto> of super::Serde { #[inline(always)] fn serialize(self: @T, ref output: Array) { output.append((*self).into()); diff --git a/corelib/src/starknet.cairo b/corelib/src/starknet.cairo index 36a11c627..da248c263 100644 --- a/corelib/src/starknet.cairo +++ b/corelib/src/starknet.cairo @@ -1,22 +1,22 @@ -use box::Box; -use option::OptionTrait; -use array::Span; -use traits::Into; -use traits::TryInto; -use zeroable::Zeroable; +use core::box::Box; +use core::option::OptionTrait; +use core::array::Span; +use core::traits::Into; +use core::traits::TryInto; +use core::zeroable::Zeroable; // Re-imports // Store -mod storage_access; +pub mod storage_access; +pub use storage_access::{Store, StorageAddress}; use storage_access::{ - Store, StorePacking, StorageAddress, StorageBaseAddress, storage_base_address_const, - storage_base_address_from_felt252, storage_address_from_base, - storage_address_from_base_and_offset, storage_address_to_felt252, + StorePacking, StorageBaseAddress, storage_base_address_const, storage_base_address_from_felt252, + storage_address_from_base, storage_address_from_base_and_offset, storage_address_to_felt252, storage_address_try_from_felt252 }; // Module containing all the extern declaration of the syscalls. -mod syscalls; +pub mod syscalls; use syscalls::{ call_contract_syscall, deploy_syscall, emit_event_syscall, get_block_hash_syscall, get_execution_info_syscall, library_call_syscall, send_message_to_l1_syscall, @@ -24,57 +24,62 @@ use syscalls::{ }; // secp256 -mod secp256_trait; -mod secp256k1; -mod secp256r1; +pub mod secp256_trait; +pub mod secp256k1; +pub mod secp256r1; // ContractAddress -mod contract_address; +pub mod contract_address; +pub use contract_address::{ContractAddress, contract_address_const}; use contract_address::{ - ContractAddress, ContractAddressIntoFelt252, Felt252TryIntoContractAddress, - contract_address_const, contract_address_to_felt252, contract_address_try_from_felt252 + ContractAddressIntoFelt252, Felt252TryIntoContractAddress, contract_address_to_felt252, + contract_address_try_from_felt252 }; // EthAddress -mod eth_address; +pub mod eth_address; +pub use eth_address::EthAddress; use eth_address::{ - EthAddress, EthAddressIntoFelt252, EthAddressSerde, EthAddressZeroable, Felt252TryIntoEthAddress + EthAddressIntoFelt252, EthAddressSerde, EthAddressZeroable, Felt252TryIntoEthAddress }; // EthSignature -mod eth_signature; +pub mod eth_signature; use eth_signature::verify_eth_signature; // ClassHash -mod class_hash; +pub mod class_hash; +pub use class_hash::ClassHash; use class_hash::{ - ClassHash, ClassHashIntoFelt252, Felt252TryIntoClassHash, class_hash_const, - class_hash_to_felt252, class_hash_try_from_felt252 + ClassHashIntoFelt252, Felt252TryIntoClassHash, class_hash_const, class_hash_to_felt252, + class_hash_try_from_felt252 }; +// Not `pub` on purpose, only used for direct reexport by the next line. mod info; -use info::{ - ExecutionInfo, BlockInfo, TxInfo, get_execution_info, get_caller_address, get_contract_address, - get_block_info, get_tx_info, get_block_timestamp +pub use info::{ + v2::ExecutionInfo as ExecutionInfo, BlockInfo, v2::TxInfo as TxInfo, get_execution_info, + get_caller_address, get_contract_address, get_block_info, get_tx_info, get_block_timestamp, + get_block_number }; -mod event; -use event::Event; +pub mod event; +pub use event::Event; -mod account; -use account::AccountContract; +pub mod account; +pub use account::AccountContract; -mod storage; +pub mod storage; -extern type System; +pub extern type System; // An Helper function to force the inclusion of `System` in the list of implicits. fn use_system_implicit() implicits(System) {} /// The result type for a syscall. -type SyscallResult = Result>; +pub type SyscallResult = Result>; -trait SyscallResultTrait { +pub trait SyscallResultTrait { /// If `val` is `Result::Ok(x)`, returns `x`. Otherwise, panics with the revert reason. fn unwrap_syscall(self: SyscallResult) -> T; } @@ -88,7 +93,7 @@ impl SyscallResultTraitImpl of SyscallResultTrait { } /// The expected return value of the `__validate*__` functions of an accounted contract. -const VALIDATED: felt252 = 'VALID'; +pub const VALIDATED: felt252 = 'VALID'; // Module for starknet testing only. -mod testing; +pub mod testing; diff --git a/corelib/src/starknet/account.cairo b/corelib/src/starknet/account.cairo index 4765a71ca..121efffc2 100644 --- a/corelib/src/starknet/account.cairo +++ b/corelib/src/starknet/account.cairo @@ -1,14 +1,14 @@ use starknet::ContractAddress; -#[derive(Drop, Serde)] -struct Call { - to: ContractAddress, - selector: felt252, - calldata: Array +#[derive(Drop, Serde, Debug)] +pub struct Call { + pub to: ContractAddress, + pub selector: felt252, + pub calldata: Span } #[starknet::interface] -trait AccountContract { +pub trait AccountContract { fn __validate_declare__(self: @TContractState, class_hash: felt252) -> felt252; fn __validate__(ref self: TContractState, calls: Array) -> felt252; fn __execute__(ref self: TContractState, calls: Array) -> Array>; diff --git a/corelib/src/starknet/class_hash.cairo b/corelib/src/starknet/class_hash.cairo index 1c1070a60..17cdf9f4b 100644 --- a/corelib/src/starknet/class_hash.cairo +++ b/corelib/src/starknet/class_hash.cairo @@ -1,51 +1,50 @@ -use zeroable::Zeroable; -use serde::Serde; -use hash::{Hash, HashStateTrait}; +use core::serde::Serde; +use core::hash::{Hash, HashStateTrait}; #[derive(Copy, Drop)] -extern type ClassHash; +pub extern type ClassHash; +pub extern fn class_hash_const() -> ClassHash nopanic; +pub(crate) extern fn class_hash_to_felt252(address: ClassHash) -> felt252 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( +pub(crate) extern fn class_hash_try_from_felt252( address: felt252 ) -> Option implicits(RangeCheck) nopanic; -impl Felt252TryIntoClassHash of TryInto { +pub(crate) impl Felt252TryIntoClassHash of TryInto { fn try_into(self: felt252) -> Option { class_hash_try_from_felt252(self) } } -impl ClassHashIntoFelt252 of Into { +pub(crate) impl ClassHashIntoFelt252 of Into { fn into(self: ClassHash) -> felt252 { class_hash_to_felt252(self) } } -impl ClassHashZeroable of Zeroable { +impl ClassHashZero of core::num::traits::Zero { fn zero() -> ClassHash { class_hash_const::<0>() } #[inline(always)] - fn is_zero(self: ClassHash) -> bool { - class_hash_to_felt252(self).is_zero() + fn is_zero(self: @ClassHash) -> bool { + core::num::traits::Zero::::is_zero(@class_hash_to_felt252(*self)) } #[inline(always)] - fn is_non_zero(self: ClassHash) -> bool { + fn is_non_zero(self: @ClassHash) -> bool { !self.is_zero() } } -impl ClassHashSerde of serde::Serde { +pub(crate) impl ClassHashZeroable = + core::zeroable::zero_based::ZeroableImpl; + +impl ClassHashSerde of Serde { fn serialize(self: @ClassHash, ref output: Array) { class_hash_to_felt252(*self).serialize(ref output); } fn deserialize(ref serialized: Span) -> Option { - Option::Some( - class_hash_try_from_felt252(serde::Serde::::deserialize(ref serialized)?)? - ) + Option::Some(class_hash_try_from_felt252(Serde::::deserialize(ref serialized)?)?) } } @@ -62,3 +61,5 @@ impl ClassHashPartialEq of PartialEq { impl HashClassHash, +Drop> = core::hash::into_felt252_based::HashImpl; + +impl DebugClassHash = core::fmt::into_felt252_based::DebugImpl; diff --git a/corelib/src/starknet/contract_address.cairo b/corelib/src/starknet/contract_address.cairo index b26acd75e..c4d7353d3 100644 --- a/corelib/src/starknet/contract_address.cairo +++ b/corelib/src/starknet/contract_address.cairo @@ -1,52 +1,54 @@ -use zeroable::Zeroable; -use serde::Serde; -use hash::{Hash, HashStateTrait}; +use core::zeroable::Zeroable; +use core::serde::Serde; +use core::hash::{Hash, HashStateTrait}; #[derive(Copy, Drop)] -extern type ContractAddress; +pub extern type ContractAddress; -extern fn contract_address_const() -> ContractAddress nopanic; -extern fn contract_address_to_felt252(address: ContractAddress) -> felt252 nopanic; +pub extern fn contract_address_const() -> ContractAddress nopanic; +pub(crate) extern fn contract_address_to_felt252(address: ContractAddress) -> felt252 nopanic; -extern fn contract_address_try_from_felt252( +pub(crate) extern fn contract_address_try_from_felt252( address: felt252 ) -> Option implicits(RangeCheck) nopanic; -impl Felt252TryIntoContractAddress of TryInto { +pub(crate) impl Felt252TryIntoContractAddress of TryInto { fn try_into(self: felt252) -> Option { contract_address_try_from_felt252(self) } } -impl ContractAddressIntoFelt252 of Into { +pub(crate) impl ContractAddressIntoFelt252 of Into { fn into(self: ContractAddress) -> felt252 { contract_address_to_felt252(self) } } -impl ContractAddressZeroable of Zeroable { + +impl ContractAddressZero of core::num::traits::Zero { fn zero() -> ContractAddress { contract_address_const::<0>() } #[inline(always)] - fn is_zero(self: ContractAddress) -> bool { - contract_address_to_felt252(self).is_zero() + fn is_zero(self: @ContractAddress) -> bool { + core::num::traits::Zero::::is_zero(@contract_address_to_felt252(*self)) } #[inline(always)] - fn is_non_zero(self: ContractAddress) -> bool { + fn is_non_zero(self: @ContractAddress) -> bool { !self.is_zero() } } -impl ContractAddressSerde of serde::Serde { +pub(crate) impl ContractAddressZeroable = + core::zeroable::zero_based::ZeroableImpl; + +impl ContractAddressSerde of Serde { fn serialize(self: @ContractAddress, ref output: Array) { contract_address_to_felt252(*self).serialize(ref output); } fn deserialize(ref serialized: Span) -> Option { Option::Some( - contract_address_try_from_felt252( - serde::Serde::::deserialize(ref serialized)? - )? + contract_address_try_from_felt252(Serde::::deserialize(ref serialized)?)? ) } } @@ -62,5 +64,27 @@ impl ContractAddressPartialEq of PartialEq { } } +impl ContractAddressPartialOrd of PartialOrd { + fn lt(lhs: ContractAddress, rhs: ContractAddress) -> bool { + // TODO(orizi): Check if implementing a libfunc for `felt252` ordering is more efficient. + let lhs: u256 = contract_address_to_felt252(lhs).into(); + lhs < contract_address_to_felt252(rhs).into() + } + #[inline(always)] + fn le(lhs: ContractAddress, rhs: ContractAddress) -> bool { + !(rhs < lhs) + } + #[inline(always)] + fn gt(lhs: ContractAddress, rhs: ContractAddress) -> bool { + rhs < lhs + } + #[inline(always)] + fn ge(lhs: ContractAddress, rhs: ContractAddress) -> bool { + !(lhs < rhs) + } +} + impl HashContractAddress, +Drop> = core::hash::into_felt252_based::HashImpl; + +impl DebugContractAddress = core::fmt::into_felt252_based::DebugImpl; diff --git a/corelib/src/starknet/eth_address.cairo b/corelib/src/starknet/eth_address.cairo index 4bc019717..2053506f7 100644 --- a/corelib/src/starknet/eth_address.cairo +++ b/corelib/src/starknet/eth_address.cairo @@ -1,16 +1,15 @@ -use debug::PrintTrait; -use integer::{u128_safe_divmod, U128TryIntoNonZero, U256TryIntoFelt252}; -use option::{Option, OptionTrait}; -use serde::Serde; -use traits::{Into, TryInto}; -use zeroable::Zeroable; +use core::debug::PrintTrait; +use core::integer::{u128_safe_divmod, U128TryIntoNonZero, U256TryIntoFelt252}; +use core::option::{Option, OptionTrait}; +use core::serde::Serde; +use core::traits::{Into, TryInto}; // An Ethereum address (160 bits). #[derive(Copy, Drop, Hash, PartialEq, starknet::Store)] -struct EthAddress { +pub struct EthAddress { address: felt252, } -impl Felt252TryIntoEthAddress of TryInto { +pub(crate) impl Felt252TryIntoEthAddress of TryInto { fn try_into(self: felt252) -> Option { let ETH_ADDRESS_BOUND = 0x10000000000000000000000000000000000000000_u256; // 2 ** 160 @@ -21,12 +20,12 @@ impl Felt252TryIntoEthAddress of TryInto { } } } -impl EthAddressIntoFelt252 of Into { +pub(crate) impl EthAddressIntoFelt252 of Into { fn into(self: EthAddress) -> felt252 { self.address } } -impl U256IntoEthAddress of Into { +pub(crate) impl U256IntoEthAddress of Into { fn into(self: u256) -> EthAddress { // The Ethereum address is the 20 least significant bytes (=160=128+32 bits) of the value. let high_32_bits = self.high % 0x100000000_u128; @@ -36,7 +35,7 @@ impl U256IntoEthAddress of Into { } } } -impl EthAddressSerde of Serde { +pub(crate) impl EthAddressSerde of Serde { fn serialize(self: @EthAddress, ref output: Array) { self.address.serialize(ref output); } @@ -44,22 +43,27 @@ impl EthAddressSerde of Serde { Serde::::deserialize(ref serialized)?.try_into() } } -impl EthAddressZeroable of Zeroable { +impl EthAddressZero of core::num::traits::Zero { fn zero() -> EthAddress { 0.try_into().unwrap() } #[inline(always)] - fn is_zero(self: EthAddress) -> bool { - self.address.is_zero() + fn is_zero(self: @EthAddress) -> bool { + core::num::traits::Zero::::is_zero(self.address) } #[inline(always)] - fn is_non_zero(self: EthAddress) -> bool { + fn is_non_zero(self: @EthAddress) -> bool { !self.is_zero() } } -impl EthAddressPrintImpl of PrintTrait { +pub(crate) impl EthAddressZeroable = + core::zeroable::zero_based::ZeroableImpl; + +pub(crate) impl EthAddressPrintImpl of PrintTrait { fn print(self: EthAddress) { self.address.print(); } } + +impl DebugEthAddress = core::fmt::into_felt252_based::DebugImpl; diff --git a/corelib/src/starknet/eth_signature.cairo b/corelib/src/starknet/eth_signature.cairo index a24ff1618..eaa91f391 100644 --- a/corelib/src/starknet/eth_signature.cairo +++ b/corelib/src/starknet/eth_signature.cairo @@ -1,4 +1,4 @@ -use option::OptionTrait; +use core::option::OptionTrait; use starknet::{ EthAddress, secp256_trait::{ @@ -6,15 +6,15 @@ use starknet::{ }, secp256k1::Secp256k1Point, SyscallResult, SyscallResultTrait }; -use keccak::keccak_u256s_be_inputs; +use core::keccak::keccak_u256s_be_inputs; /// Asserts that an Ethereum signature is valid w.r.t. a given Eth address /// Also verifies that r and s components of the signature are in the range (0, N), /// where N is the size of the curve. -fn verify_eth_signature(msg_hash: u256, signature: Signature, eth_address: EthAddress) { +pub fn verify_eth_signature(msg_hash: u256, signature: Signature, eth_address: EthAddress) { match is_eth_signature_valid(:msg_hash, :signature, :eth_address) { Result::Ok(()) => {}, - Result::Err(err) => panic_with_felt252(err), + Result::Err(err) => core::panic_with_felt252(err), } } @@ -22,7 +22,7 @@ fn verify_eth_signature(msg_hash: u256, signature: Signature, eth_address: EthAd /// Also verifies that r and s components of the signature are in the range (0, N), /// where N is the size of the curve. /// Returns a Result with an error string if the signature is invalid. -fn is_eth_signature_valid( +pub fn is_eth_signature_valid( msg_hash: u256, signature: Signature, eth_address: EthAddress ) -> Result<(), felt252> { if !is_signature_entry_valid::(signature.r) { @@ -41,7 +41,7 @@ fn is_eth_signature_valid( } /// Converts a public key point to the corresponding Ethereum address. -fn public_key_point_to_eth_address< +pub fn public_key_point_to_eth_address< Secp256Point, +Drop, +Secp256Trait, +Secp256PointTrait >( public_key_point: Secp256Point @@ -51,8 +51,8 @@ fn public_key_point_to_eth_address< // Keccak output is little endian. let point_hash_le = keccak_u256s_be_inputs(array![x, y].span()); let point_hash = u256 { - low: integer::u128_byte_reverse(point_hash_le.high), - high: integer::u128_byte_reverse(point_hash_le.low) + low: core::integer::u128_byte_reverse(point_hash_le.high), + high: core::integer::u128_byte_reverse(point_hash_le.low) }; point_hash.into() diff --git a/corelib/src/starknet/event.cairo b/corelib/src/starknet/event.cairo index cf3ee2b78..157ca97d2 100644 --- a/corelib/src/starknet/event.cairo +++ b/corelib/src/starknet/event.cairo @@ -1,8 +1,8 @@ -trait Event { +pub trait Event { fn append_keys_and_data(self: @T, ref keys: Array, ref data: Array); fn deserialize(ref keys: Span, ref data: Span) -> Option; } -trait EventEmitter { - fn emit>(ref self: T, event: S); +pub trait EventEmitter { + fn emit>(ref self: T, event: S); } diff --git a/corelib/src/starknet/info.cairo b/corelib/src/starknet/info.cairo index 20b427a95..631db1ba9 100644 --- a/corelib/src/starknet/info.cairo +++ b/corelib/src/starknet/info.cairo @@ -2,132 +2,132 @@ use starknet::{ SyscallResultTrait, SyscallResult, syscalls::get_execution_info_syscall, contract_address::ContractAddress }; -use box::BoxTrait; +use core::box::BoxTrait; -#[derive(Copy, Drop)] -struct ExecutionInfo { - block_info: Box, - tx_info: Box, - caller_address: ContractAddress, - contract_address: ContractAddress, - entry_point_selector: felt252, +#[derive(Copy, Drop, Debug)] +pub struct ExecutionInfo { + pub block_info: Box, + pub tx_info: Box, + pub caller_address: ContractAddress, + pub contract_address: ContractAddress, + pub entry_point_selector: felt252, } -#[derive(Copy, Drop, Serde)] -struct BlockInfo { - block_number: u64, - block_timestamp: u64, - sequencer_address: ContractAddress, +#[derive(Copy, Drop, Debug, Serde)] +pub struct BlockInfo { + pub block_number: u64, + pub block_timestamp: u64, + pub sequencer_address: ContractAddress, } -#[derive(Copy, Drop, Serde)] -struct TxInfo { +#[derive(Copy, Drop, Debug, Serde)] +pub struct TxInfo { // The version of the transaction. It is fixed (currently, 1) in the OS, and should be // signed by the account contract. // This field allows invalidating old transactions, whenever the meaning of the other // transaction fields is changed (in the OS). - version: felt252, + pub version: felt252, // The account contract from which this transaction originates. - account_contract_address: ContractAddress, + pub account_contract_address: ContractAddress, // The max_fee field of the transaction. - max_fee: u128, + pub max_fee: u128, // The signature of the transaction. - signature: Span, + pub signature: Span, // The hash of the transaction. - transaction_hash: felt252, + pub transaction_hash: felt252, // The identifier of the chain. // This field can be used to prevent replay of testnet transactions on mainnet. - chain_id: felt252, + pub chain_id: felt252, // The transaction's nonce. - nonce: felt252, + pub nonce: felt252, } -fn get_execution_info() -> Box { - get_execution_info_syscall().unwrap_syscall() +pub fn get_execution_info() -> Box { + starknet::syscalls::get_execution_info_v2_syscall().unwrap_syscall() } -fn get_caller_address() -> ContractAddress { +pub fn get_caller_address() -> ContractAddress { get_execution_info().unbox().caller_address } -fn get_contract_address() -> ContractAddress { +pub fn get_contract_address() -> ContractAddress { get_execution_info().unbox().contract_address } -fn get_block_info() -> Box { +pub fn get_block_info() -> Box { get_execution_info().unbox().block_info } -fn get_tx_info() -> Box { +pub fn get_tx_info() -> Box { get_execution_info().unbox().tx_info } -fn get_block_timestamp() -> u64 { +pub fn get_block_timestamp() -> u64 { get_block_info().unbox().block_timestamp } -fn get_block_number() -> u64 { +pub fn get_block_number() -> u64 { get_block_info().unbox().block_number } /// The extended version of the `get_execution_info` syscall result. -mod v2 { +pub mod v2 { use starknet::contract_address::ContractAddress; use super::BlockInfo; - #[derive(Copy, Drop)] - struct ExecutionInfo { - block_info: Box, - tx_info: Box, - caller_address: ContractAddress, - contract_address: ContractAddress, - entry_point_selector: felt252, + #[derive(Copy, Drop, Debug)] + pub struct ExecutionInfo { + pub block_info: Box, + pub tx_info: Box, + pub caller_address: ContractAddress, + pub contract_address: ContractAddress, + pub entry_point_selector: felt252, } - #[derive(Copy, Drop, Serde)] - struct TxInfo { + #[derive(Copy, Drop, Debug, Serde)] + pub struct TxInfo { // The version of the transaction. It is fixed (currently, 1) in the OS, and should be // signed by the account contract. // This field allows invalidating old transactions, whenever the meaning of the other // transaction fields is changed (in the OS). - version: felt252, + pub version: felt252, // The account contract from which this transaction originates. - account_contract_address: ContractAddress, + pub account_contract_address: ContractAddress, // The max_fee field of the transaction. - max_fee: u128, + pub max_fee: u128, // The signature of the transaction. - signature: Span, + pub signature: Span, // The hash of the transaction. - transaction_hash: felt252, + pub transaction_hash: felt252, // The identifier of the chain. // This field can be used to prevent replay of testnet transactions on mainnet. - chain_id: felt252, + pub chain_id: felt252, // The transaction's nonce. - nonce: felt252, + pub nonce: felt252, // A span of ResourceBounds structs. - resource_bounds: Span, + pub resource_bounds: Span, // The tip. - tip: u128, + pub tip: u128, // If specified, the paymaster should pay for the execution of the tx. // The data includes the address of the paymaster sponsoring the transaction, followed by // extra data to send to the paymaster. - paymaster_data: Span, + pub paymaster_data: Span, // The data availability mode for the nonce. - nonce_data_availabilty_mode: u32, + pub nonce_data_availability_mode: u32, // The data availability mode for the account balance from which fee will be taken. - fee_data_availabilty_mode: u32, + pub fee_data_availability_mode: u32, // If nonempty, will contain the required data for deploying and initializing an account // contract: its class hash, address salt and constructor calldata. - account_deployment_data: Span, + pub account_deployment_data: Span, } - #[derive(Copy, Drop, Serde)] - struct ResourceBounds { + #[derive(Copy, Drop, Debug, Serde)] + pub struct ResourceBounds { // The name of the resource. - resource: felt252, + pub resource: felt252, // The maximum amount of the resource allowed for usage during the execution. - max_amount: u64, + pub max_amount: u64, // The maximum price the user is willing to pay for the resource unit. - max_price_per_unit: u128, + pub max_price_per_unit: u128, } } diff --git a/corelib/src/starknet/secp256_trait.cairo b/corelib/src/starknet/secp256_trait.cairo index 181cd3400..1fda813d6 100644 --- a/corelib/src/starknet/secp256_trait.cairo +++ b/corelib/src/starknet/secp256_trait.cairo @@ -1,20 +1,20 @@ -use array::ArrayTrait; -use math::{u256_mul_mod_n, inv_mod}; -use option::OptionTrait; +use core::array::ArrayTrait; +use core::math::{u256_mul_mod_n, u256_inv_mod}; +use core::option::OptionTrait; use starknet::{eth_address::U256IntoEthAddress, EthAddress, SyscallResult, SyscallResultTrait}; -use traits::{Into, TryInto}; -use integer::U256TryIntoNonZero; +use core::traits::{Into, TryInto}; +use core::integer::U256TryIntoNonZero; /// Secp256{k/r}1 ECDSA signature. -#[derive(Copy, Drop, PartialEq, Serde, starknet::Store, Hash)] -struct Signature { - r: u256, - s: u256, +#[derive(Copy, Drop, Debug, PartialEq, Serde, starknet::Store, Hash)] +pub struct Signature { + pub r: u256, + pub s: u256, // The parity of the y coordinate of the ec point whose x coordinate is `r`. // `y_parity` == true means that the y coordinate is odd. // Some places use non boolean v instead of y_parity. // In that case, `signature_from_vrs` should be used. - y_parity: bool, + pub y_parity: bool, } @@ -22,11 +22,11 @@ struct Signature { /// `v` is the sum of an odd number and the parity of the y coordinate of the ec point whose x /// coordinate is `r`. /// See https://eips.ethereum.org/EIPS/eip-155 for more details. -fn signature_from_vrs(v: u32, r: u256, s: u256) -> Signature { +pub fn signature_from_vrs(v: u32, r: u256, s: u256) -> Signature { Signature { r, s, y_parity: v % 2 == 0 } } -trait Secp256Trait { +pub trait Secp256Trait { fn get_curve_size() -> u256; fn get_generator_point() -> Secp256Point; @@ -36,14 +36,14 @@ trait Secp256Trait { ) -> SyscallResult>; } -trait Secp256PointTrait { +pub trait Secp256PointTrait { fn get_coordinates(self: Secp256Point) -> SyscallResult<(u256, u256)>; fn add(self: Secp256Point, other: Secp256Point) -> SyscallResult; fn mul(self: Secp256Point, scalar: u256) -> SyscallResult; } /// Checks whether `value` is in the range [1, N), where N is the size of the curve. -fn is_signature_entry_valid< +pub fn is_signature_entry_valid< Secp256Point, +Drop, impl Secp256Impl: Secp256Trait >( value: u256 @@ -51,7 +51,7 @@ fn is_signature_entry_valid< value != 0_u256 && value < Secp256Impl::get_curve_size() } -fn is_valid_signature< +pub fn is_valid_signature< Secp256Point, +Drop, impl Secp256Impl: Secp256Trait, @@ -65,7 +65,7 @@ fn is_valid_signature< } let n_nz = Secp256Impl::get_curve_size().try_into().unwrap(); - let s_inv = inv_mod(s.try_into().unwrap(), n_nz).unwrap(); + let s_inv = u256_inv_mod(s.try_into().unwrap(), n_nz).unwrap().into(); let u1 = u256_mul_mod_n(msg_hash, s_inv, n_nz); let u2 = u256_mul_mod_n(r, s_inv, n_nz); @@ -74,13 +74,13 @@ fn is_valid_signature< let point2 = public_key.mul(u2).unwrap_syscall(); let sum = point1.add(point2).unwrap_syscall(); - let (x, y) = sum.get_coordinates().unwrap_syscall(); + let (x, _y) = sum.get_coordinates().unwrap_syscall(); x == r } /// Receives a signature and the signed message hash. /// Returns the public key associated with the signer, represented as a point on the curve. -fn recover_public_key< +pub fn recover_public_key< Secp256Point, +Drop, impl Secp256Impl: Secp256Trait, @@ -98,7 +98,7 @@ fn recover_public_key< // where the divisions by `r` are modulo `N` (the size of the curve). let n_nz = Secp256Impl::get_curve_size().try_into().unwrap(); - let r_inv = inv_mod(r.try_into().unwrap(), n_nz).unwrap(); + let r_inv = u256_inv_mod(r.try_into().unwrap(), n_nz).unwrap().into(); let u1 = u256_mul_mod_n(msg_hash, r_inv, n_nz); let minus_u1 = secp256_ec_negate_scalar::(u1); diff --git a/corelib/src/starknet/secp256k1.cairo b/corelib/src/starknet/secp256k1.cairo index d02e0a202..a3a4f24a7 100644 --- a/corelib/src/starknet/secp256k1.cairo +++ b/corelib/src/starknet/secp256k1.cairo @@ -1,7 +1,7 @@ //! This module contains functions and constructs related to elliptic curve operations on the //! secp256k1 curve. -use option::OptionTrait; +use core::option::OptionTrait; use starknet::{ secp256_trait::{ Secp256Trait, Secp256PointTrait, recover_public_key, is_signature_entry_valid, Signature @@ -10,9 +10,9 @@ use starknet::{ }; #[derive(Copy, Drop)] -extern type Secp256k1Point; +pub extern type Secp256k1Point; -impl Secp256k1Impl of Secp256Trait { +pub(crate) impl Secp256k1Impl of Secp256Trait { // TODO(yuval): change to constant once u256 constants are supported. fn get_curve_size() -> u256 { 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141 @@ -37,7 +37,7 @@ impl Secp256k1Impl of Secp256Trait { } } -impl Secp256k1PointImpl of Secp256PointTrait { +pub(crate) impl Secp256k1PointImpl of Secp256PointTrait { fn get_coordinates(self: Secp256k1Point) -> SyscallResult<(u256, u256)> { secp256k1_get_xy_syscall(self) } diff --git a/corelib/src/starknet/secp256r1.cairo b/corelib/src/starknet/secp256r1.cairo index 65fdfcc86..362fe7990 100644 --- a/corelib/src/starknet/secp256r1.cairo +++ b/corelib/src/starknet/secp256r1.cairo @@ -1,15 +1,15 @@ //! This module contains functions and constructs related to elliptic curve operations on the //! secp256r1 curve. -use option::OptionTrait; +use core::option::OptionTrait; use starknet::{ EthAddress, secp256_trait::{Secp256Trait, Secp256PointTrait}, SyscallResult, SyscallResultTrait }; #[derive(Copy, Drop)] -extern type Secp256r1Point; +pub extern type Secp256r1Point; -impl Secp256r1Impl of Secp256Trait { +pub(crate) impl Secp256r1Impl of Secp256Trait { // TODO(yuval): change to constant once u256 constants are supported. fn get_curve_size() -> u256 { 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551 @@ -34,7 +34,7 @@ impl Secp256r1Impl of Secp256Trait { } } -impl Secp256r1PointImpl of Secp256PointTrait { +pub(crate) impl Secp256r1PointImpl of Secp256PointTrait { fn get_coordinates(self: Secp256r1Point) -> SyscallResult<(u256, u256)> { secp256r1_get_xy_syscall(self) } diff --git a/corelib/src/starknet/storage.cairo b/corelib/src/starknet/storage.cairo index 1818a0cdc..ac2dabc25 100644 --- a/corelib/src/starknet/storage.cairo +++ b/corelib/src/starknet/storage.cairo @@ -1,16 +1,16 @@ /// Trait for getting the address of any contract/component storage member. -trait StorageMemberAddressTrait { +pub trait StorageMemberAddressTrait { fn address(self: @TMemberState) -> starknet::StorageBaseAddress nopanic; } /// Trait for accessing any contract/component storage member. -trait StorageMemberAccessTrait { +pub trait StorageMemberAccessTrait { fn read(self: @TMemberState) -> TValue; fn write(ref self: TMemberState, value: TValue); } /// Implementation of StorageMemberAccessTrait for types that implement StorageMemberAddressTrait. -impl StorageMemberAccessImpl< +pub impl StorageMemberAccessImpl< TMemberState, TValue, +StorageMemberAddressTrait, @@ -20,7 +20,7 @@ impl StorageMemberAccessImpl< fn read(self: @TMemberState) -> TValue { // Only address_domain 0 is currently supported. let address_domain = 0_u32; - starknet::SyscallResultTraitImpl::unwrap_syscall( + starknet::SyscallResultTrait::unwrap_syscall( starknet::Store::::read(address_domain, self.address()) ) } @@ -28,24 +28,24 @@ impl StorageMemberAccessImpl< // Only address_domain 0 is currently supported. let address_domain = 0_u32; let write_result = starknet::Store::::write(address_domain, self.address(), value); - starknet::SyscallResultTraitImpl::unwrap_syscall(write_result) + starknet::SyscallResultTrait::unwrap_syscall(write_result) } } /// Trait for getting the address of any contract/component mapping storage member. -trait StorageMapMemberAddressTrait { +pub trait StorageMapMemberAddressTrait { fn address(self: @TMemberState, key: TKey) -> starknet::StorageBaseAddress; } /// Trait for accessing any contract/component storage member. -trait StorageMapMemberAccessTrait { +pub trait StorageMapMemberAccessTrait { fn read(self: @TMemberState, key: TKey) -> TValue; fn write(ref self: TMemberState, key: TKey, value: TValue); } /// Implementation of StorageMapMemberAccessTrait for types that implement /// StorageMapMemberAddressTrait. -impl StorageMapMemberAccessImpl< +pub impl StorageMapMemberAccessImpl< TMemberState, TKey, TValue, @@ -57,14 +57,14 @@ impl StorageMapMemberAccessImpl< fn read(self: @TMemberState, key: TKey) -> TValue { // Only address_domain 0 is currently supported. let address_domain = 0_u32; - starknet::SyscallResultTraitImpl::unwrap_syscall( + starknet::SyscallResultTrait::unwrap_syscall( starknet::Store::::read(address_domain, self.address(key)) ) } fn write(ref self: TMemberState, key: TKey, value: TValue) { // Only address_domain 0 is currently supported. let address_domain = 0_u32; - starknet::SyscallResultTraitImpl::unwrap_syscall( + starknet::SyscallResultTrait::unwrap_syscall( starknet::Store::::write(address_domain, self.address(key), value) ) } diff --git a/corelib/src/starknet/storage_access.cairo b/corelib/src/starknet/storage_access.cairo index 43dc3ee7c..ad8836792 100644 --- a/corelib/src/starknet/storage_access.cairo +++ b/corelib/src/starknet/storage_access.cairo @@ -1,33 +1,35 @@ use core::array::ArrayTrait; -use traits::{Into, TryInto}; -use option::OptionTrait; +use core::traits::{Into, TryInto}; +use core::option::OptionTrait; +use core::byte_array::ByteArrayTrait; +use core::bytes_31::BYTES_IN_BYTES31; use starknet::{ SyscallResult, syscalls::{storage_read_syscall, storage_write_syscall}, contract_address::{ContractAddress, Felt252TryIntoContractAddress, ContractAddressIntoFelt252}, class_hash::{ClassHash, Felt252TryIntoClassHash, ClassHashIntoFelt252} }; -use serde::Serde; +use core::serde::Serde; #[derive(Copy, Drop)] -extern type StorageAddress; +pub extern type StorageAddress; #[derive(Copy, Drop)] -extern type StorageBaseAddress; +pub extern type StorageBaseAddress; // Storage. -extern fn storage_base_address_const() -> StorageBaseAddress nopanic; -extern fn storage_base_address_from_felt252( +pub extern fn storage_base_address_const() -> StorageBaseAddress nopanic; +pub extern fn storage_base_address_from_felt252( addr: felt252 ) -> StorageBaseAddress implicits(RangeCheck) nopanic; -extern fn storage_address_to_felt252(address: StorageAddress) -> felt252 nopanic; -extern fn storage_address_from_base_and_offset( +pub(crate) extern fn storage_address_to_felt252(address: StorageAddress) -> felt252 nopanic; +pub extern fn storage_address_from_base_and_offset( base: StorageBaseAddress, offset: u8 ) -> StorageAddress nopanic; -extern fn storage_address_from_base(base: StorageBaseAddress) -> StorageAddress nopanic; +pub extern fn storage_address_from_base(base: StorageBaseAddress) -> StorageAddress nopanic; -extern fn storage_address_try_from_felt252( +pub(crate) extern fn storage_address_try_from_felt252( address: felt252 ) -> Option implicits(RangeCheck) nopanic; @@ -42,31 +44,49 @@ impl StorageAddressIntoFelt252 of Into { } } -impl StorageAddressSerde of serde::Serde { +impl StorageAddressSerde of Serde { fn serialize(self: @StorageAddress, ref output: Array) { storage_address_to_felt252(*self).serialize(ref output); } fn deserialize(ref serialized: Span) -> Option { Option::Some( - storage_address_try_from_felt252(serde::Serde::::deserialize(ref serialized)?)? + storage_address_try_from_felt252(Serde::::deserialize(ref serialized)?)? ) } } -trait Store { +impl DebugStorageAddress = core::fmt::into_felt252_based::DebugImpl; +impl DebugStorageBaseAddress of core::fmt::Debug { + fn fmt(self: @StorageBaseAddress, ref f: core::fmt::Formatter) -> Result<(), core::fmt::Error> { + DebugStorageAddress::fmt(@storage_address_from_base(*self), ref f) + } +} + +/// Trait for types that can be used as a value in Starknet storage variables. +pub trait Store { + /// Reads a value from storage from domain `address_domain` and base address `base`. fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult; + /// Writes a value to storage to domain `address_domain` and base address `base`. fn write(address_domain: u32, base: StorageBaseAddress, value: T) -> SyscallResult<()>; + /// Reads a value from storage from domain `address_domain` and base address `base` at offset + /// `offset`. fn read_at_offset( address_domain: u32, base: StorageBaseAddress, offset: u8 ) -> SyscallResult; + /// Writes a value to storage to domain `address_domain` and base address `base` at offset + /// `offset`. fn write_at_offset( address_domain: u32, base: StorageBaseAddress, offset: u8, value: T ) -> SyscallResult<()>; fn size() -> u8; } -trait StorePacking { +/// Trait for easier implementation of `Store` used for packing and unpacking values into values +/// that already implement `Store`, and having `Store` implemented using this conversion. +pub trait StorePacking { + /// Packs a value of type `T` into a value of type `PackedT`. fn pack(value: T) -> PackedT; + /// Unpacks a value of type `PackedT` into a value of type `T`. fn unpack(value: PackedT) -> T; } @@ -128,295 +148,163 @@ impl StoreFelt252 of Store { } } -impl StoreBool of Store { - fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult { - Result::Ok(Store::::read(address_domain, base)? != 0) - } - #[inline(always)] - fn write(address_domain: u32, base: StorageBaseAddress, value: bool) -> SyscallResult<()> { - Store::::write(address_domain, base, if value { - 1 - } else { - 0 - }) - } - #[inline(always)] - fn read_at_offset( - address_domain: u32, base: StorageBaseAddress, offset: u8 - ) -> SyscallResult { - Result::Ok(Store::::read_at_offset(address_domain, base, offset)? != 0) - } - #[inline(always)] - fn write_at_offset( - address_domain: u32, base: StorageBaseAddress, offset: u8, value: bool - ) -> SyscallResult<()> { - Store::::write_at_offset(address_domain, base, offset, if value { - 1 - } else { - 0 - }) +impl StorePackingBool of StorePacking { + fn pack(value: bool) -> felt252 { + value.into() } - #[inline(always)] - fn size() -> u8 { - 1_u8 + #[inline] + fn unpack(value: felt252) -> bool { + value != 0 } } -impl StoreU8 of Store { - fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult { - Result::Ok( - Store::::read(address_domain, base)?.try_into().expect('StoreU8 - non u8') - ) - } - #[inline(always)] - fn write(address_domain: u32, base: StorageBaseAddress, value: u8) -> SyscallResult<()> { - Store::::write(address_domain, base, value.into()) - } - #[inline(always)] - fn read_at_offset( - address_domain: u32, base: StorageBaseAddress, offset: u8 - ) -> SyscallResult { - Result::Ok( - Store::::read_at_offset(address_domain, base, offset)? - .try_into() - .expect('StoreU8 - non u8') - ) +impl StorePackingU8 of StorePacking { + fn pack(value: u8) -> felt252 { + value.into() } - #[inline(always)] - fn write_at_offset( - address_domain: u32, base: StorageBaseAddress, offset: u8, value: u8 - ) -> SyscallResult<()> { - Store::::write_at_offset(address_domain, base, offset, value.into()) - } - #[inline(always)] - fn size() -> u8 { - 1_u8 + #[inline] + fn unpack(value: felt252) -> u8 { + value.try_into().expect('StoreU8 - non u8') } } -impl StoreU16 of Store { - fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult { - Result::Ok( - Store::::read(address_domain, base)?.try_into().expect('StoreU16 - non u16') - ) +impl StorePackingI8 of StorePacking { + fn pack(value: i8) -> felt252 { + value.into() } - #[inline(always)] - fn write(address_domain: u32, base: StorageBaseAddress, value: u16) -> SyscallResult<()> { - Store::::write(address_domain, base, value.into()) + #[inline] + fn unpack(value: felt252) -> i8 { + value.try_into().expect('StoreI8 - non i8') } - #[inline(always)] - fn read_at_offset( - address_domain: u32, base: StorageBaseAddress, offset: u8 - ) -> SyscallResult { - Result::Ok( - Store::::read_at_offset(address_domain, base, offset)? - .try_into() - .expect('StoreU16 - non u16') - ) - } - #[inline(always)] - fn write_at_offset( - address_domain: u32, base: StorageBaseAddress, offset: u8, value: u16 - ) -> SyscallResult<()> { - Store::::write_at_offset(address_domain, base, offset, value.into()) +} + +impl StorePackingU16 of StorePacking { + fn pack(value: u16) -> felt252 { + value.into() } - #[inline(always)] - fn size() -> u8 { - 1_u8 + #[inline] + fn unpack(value: felt252) -> u16 { + value.try_into().expect('StoreU16 - non u16') } } -impl StoreU32 of Store { - fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult { - Result::Ok( - Store::::read(address_domain, base)?.try_into().expect('StoreU32 - non u32') - ) +impl StorePackingI16 of StorePacking { + fn pack(value: i16) -> felt252 { + value.into() } - #[inline(always)] - fn write(address_domain: u32, base: StorageBaseAddress, value: u32) -> SyscallResult<()> { - Store::::write(address_domain, base, value.into()) - } - #[inline(always)] - fn read_at_offset( - address_domain: u32, base: StorageBaseAddress, offset: u8 - ) -> SyscallResult { - Result::Ok( - Store::::read_at_offset(address_domain, base, offset)? - .try_into() - .expect('StoreU32 - non u32') - ) + #[inline] + fn unpack(value: felt252) -> i16 { + value.try_into().expect('StoreI16 - non i16') } - #[inline(always)] - fn write_at_offset( - address_domain: u32, base: StorageBaseAddress, offset: u8, value: u32 - ) -> SyscallResult<()> { - Store::::write_at_offset(address_domain, base, offset, value.into()) +} + +impl StorePackingU32 of StorePacking { + fn pack(value: u32) -> felt252 { + value.into() } - #[inline(always)] - fn size() -> u8 { - 1_u8 + #[inline] + fn unpack(value: felt252) -> u32 { + value.try_into().expect('StoreU32 - non u32') } } -impl StoreU64 of Store { - fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult { - Result::Ok( - Store::::read(address_domain, base)?.try_into().expect('StoreU64 - non u64') - ) - } - #[inline(always)] - fn write(address_domain: u32, base: StorageBaseAddress, value: u64) -> SyscallResult<()> { - Store::::write(address_domain, base, value.into()) +impl StorePackingI32 of StorePacking { + fn pack(value: i32) -> felt252 { + value.into() } - #[inline(always)] - fn read_at_offset( - address_domain: u32, base: StorageBaseAddress, offset: u8 - ) -> SyscallResult { - Result::Ok( - Store::::read_at_offset(address_domain, base, offset)? - .try_into() - .expect('StoreU64 - non u64') - ) + #[inline] + fn unpack(value: felt252) -> i32 { + value.try_into().expect('StoreI32 - non i32') } - #[inline(always)] - fn write_at_offset( - address_domain: u32, base: StorageBaseAddress, offset: u8, value: u64 - ) -> SyscallResult<()> { - Store::::write_at_offset(address_domain, base, offset, value.into()) +} + +impl StorePackingU64 of StorePacking { + fn pack(value: u64) -> felt252 { + value.into() } - #[inline(always)] - fn size() -> u8 { - 1_u8 + #[inline] + fn unpack(value: felt252) -> u64 { + value.try_into().expect('StoreU64 - non u64') } } -impl StoreU128 of Store { - fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult { - Result::Ok( - Store::::read(address_domain, base)?.try_into().expect('StoreU128 - non u128') - ) +impl StorePackingI64 of StorePacking { + fn pack(value: i64) -> felt252 { + value.into() } - #[inline(always)] - fn write(address_domain: u32, base: StorageBaseAddress, value: u128) -> SyscallResult<()> { - Store::::write(address_domain, base, value.into()) + #[inline] + fn unpack(value: felt252) -> i64 { + value.try_into().expect('StoreI64 - non i64') } - #[inline(always)] - fn read_at_offset( - address_domain: u32, base: StorageBaseAddress, offset: u8 - ) -> SyscallResult { - Result::Ok( - Store::::read_at_offset(address_domain, base, offset)? - .try_into() - .expect('StoreU128 - non u128') - ) - } - #[inline(always)] - fn write_at_offset( - address_domain: u32, base: StorageBaseAddress, offset: u8, value: u128 - ) -> SyscallResult<()> { - Store::::write_at_offset(address_domain, base, offset, value.into()) +} + +impl StorePackingU128 of StorePacking { + fn pack(value: u128) -> felt252 { + value.into() } - #[inline(always)] - fn size() -> u8 { - 1_u8 + #[inline] + fn unpack(value: felt252) -> u128 { + value.try_into().expect('StoreU128 - non u128') } } -impl StoreStorageAddress of Store { - fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult { - Result::Ok( - Store::::read(address_domain, base)?.try_into().expect('Non StorageAddress') - ) +impl StorePackingI128 of StorePacking { + fn pack(value: i128) -> felt252 { + value.into() } - #[inline(always)] - fn write( - address_domain: u32, base: StorageBaseAddress, value: StorageAddress - ) -> SyscallResult<()> { - Store::::write(address_domain, base, value.into()) - } - #[inline(always)] - fn read_at_offset( - address_domain: u32, base: StorageBaseAddress, offset: u8 - ) -> SyscallResult { - Result::Ok( - Store::::read_at_offset(address_domain, base, offset)? - .try_into() - .expect('Non StorageAddress') - ) + #[inline] + fn unpack(value: felt252) -> i128 { + value.try_into().expect('StoreI128 - non i128') } - #[inline(always)] - fn write_at_offset( - address_domain: u32, base: StorageBaseAddress, offset: u8, value: StorageAddress - ) -> SyscallResult<()> { - Store::::write_at_offset(address_domain, base, offset, value.into()) +} + +impl StorePackingBytes31 of StorePacking { + fn pack(value: bytes31) -> felt252 { + value.into() } - #[inline(always)] - fn size() -> u8 { - 1_u8 + #[inline] + fn unpack(value: felt252) -> bytes31 { + value.try_into().expect('StoreBytes31 - non bytes31') } } -impl StoreContractAddress of Store { - fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult { - Result::Ok( - Store::::read(address_domain, base)?.try_into().expect('Non ContractAddress') - ) +impl StorePackingNonZero>> of StorePacking, T> { + fn pack(value: NonZero) -> T { + value.into() } - #[inline(always)] - fn write( - address_domain: u32, base: StorageBaseAddress, value: ContractAddress - ) -> SyscallResult<()> { - Store::::write(address_domain, base, value.into()) + #[inline] + fn unpack(value: T) -> NonZero { + value.try_into().expect('StoreNonZero - zero value') } - #[inline(always)] - fn read_at_offset( - address_domain: u32, base: StorageBaseAddress, offset: u8 - ) -> SyscallResult { - Result::Ok( - Store::::read_at_offset(address_domain, base, offset)? - .try_into() - .expect('Non ContractAddress') - ) - } - #[inline(always)] - fn write_at_offset( - address_domain: u32, base: StorageBaseAddress, offset: u8, value: ContractAddress - ) -> SyscallResult<()> { - Store::::write_at_offset(address_domain, base, offset, value.into()) +} + +impl StorePackingStorageAddress of StorePacking { + fn pack(value: StorageAddress) -> felt252 { + value.into() } - #[inline(always)] - fn size() -> u8 { - 1_u8 + #[inline] + fn unpack(value: felt252) -> StorageAddress { + value.try_into().expect('Non StorageAddress') } } -impl StoreClassHash of Store { - fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult { - Result::Ok(Store::::read(address_domain, base)?.try_into().expect('Non ClassHash')) +impl StorePackingContractAddress of StorePacking { + fn pack(value: ContractAddress) -> felt252 { + value.into() } - #[inline(always)] - fn write(address_domain: u32, base: StorageBaseAddress, value: ClassHash) -> SyscallResult<()> { - Store::::write(address_domain, base, value.into()) - } - #[inline(always)] - fn read_at_offset( - address_domain: u32, base: StorageBaseAddress, offset: u8 - ) -> SyscallResult { - Result::Ok( - Store::::read_at_offset(address_domain, base, offset)? - .try_into() - .expect('Non ClassHash') - ) + #[inline] + fn unpack(value: felt252) -> ContractAddress { + value.try_into().expect('Non ContractAddress') } - #[inline(always)] - fn write_at_offset( - address_domain: u32, base: StorageBaseAddress, offset: u8, value: ClassHash - ) -> SyscallResult<()> { - Store::::write_at_offset(address_domain, base, offset, value.into()) +} + +impl StorePackingClassHash of StorePacking { + fn pack(value: ClassHash) -> felt252 { + value.into() } - #[inline(always)] - fn size() -> u8 { - 1_u8 + #[inline] + fn unpack(value: felt252) -> ClassHash { + value.try_into().expect('Non ClassHash') } } @@ -644,7 +532,6 @@ impl TupleSize4Store< } } - impl ResultStore, +Store, +Drop, +Drop> of Store> { #[inline(always)] fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult> { @@ -712,7 +599,7 @@ impl ResultStore, +Store, +Drop, +Drop> of Store u8 { - 1 + cmp::max(Store::::size(), Store::::size()) + 1 + core::cmp::max(Store::::size(), Store::::size()) } } @@ -765,7 +652,7 @@ impl OptionStore, +Drop,> of Store> { Store::write(address_domain, base, 1)?; Store::write_at_offset(address_domain, base, 1_u8, x)?; }, - Option::None(x) => { Store::write(address_domain, base, 0)?; } + Option::None(_x) => { Store::write(address_domain, base, 0)?; } }; starknet::SyscallResult::Ok(()) } @@ -774,3 +661,153 @@ impl OptionStore, +Drop,> of Store> { 1 + Store::::size() } } + +/// Store for a `ByteArray`. +/// +/// The layout of a `ByteArray` in storage is as follows: +/// * Only the length in bytes is stored in the original address where the byte array is logically +/// stored. +/// * The actual data is stored in chunks of 256 `bytes31`s in another place in storage +/// determined by the hash of: +/// - The address storing the length of the array. +/// - The chunk index. +/// - The short string `ByteArray`. +impl ByteArrayStore of Store { + #[inline(always)] + fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult { + inner_read_byte_array(address_domain, storage_address_from_base(base)) + } + #[inline(always)] + fn write(address_domain: u32, base: StorageBaseAddress, value: ByteArray) -> SyscallResult<()> { + inner_write_byte_array(address_domain, storage_address_from_base(base), value) + } + #[inline(always)] + fn read_at_offset( + address_domain: u32, base: StorageBaseAddress, offset: u8 + ) -> SyscallResult { + inner_read_byte_array(address_domain, storage_address_from_base_and_offset(base, offset)) + } + #[inline(always)] + fn write_at_offset( + address_domain: u32, base: StorageBaseAddress, offset: u8, value: ByteArray + ) -> SyscallResult<()> { + inner_write_byte_array( + address_domain, storage_address_from_base_and_offset(base, offset), value + ) + } + #[inline(always)] + fn size() -> u8 { + 1 + } +} + +/// Returns a pointer to the `chunk`'th chunk of the byte array at `address`. +/// The pointer is the `Poseidon` hash of: +/// * `address` - The address of the ByteArray (where the length is stored). +/// * `chunk` - The index of the chunk. +/// * The short string `ByteArray` is used as the capacity argument of the sponge construction +/// (domain separation). +fn inner_byte_array_pointer(address: StorageAddress, chunk: felt252) -> StorageBaseAddress { + let (r, _, _) = core::poseidon::hades_permutation(address.into(), chunk, 'ByteArray'_felt252); + storage_base_address_from_felt252(r) +} + +/// Reads a byte array from storage from domain `address_domain` and address `address`. +/// The length of the byte array is read from `address` at domain `address_domain`. +/// For more info read the documentation of `ByteArrayStore`. +fn inner_read_byte_array(address_domain: u32, address: StorageAddress) -> SyscallResult { + let len: usize = + match starknet::syscalls::storage_read_syscall(address_domain, address)?.try_into() { + Option::Some(x) => x, + Option::None => { return SyscallResult::Err(array!['Invalid ByteArray length']); }, + }; + let (mut remaining_full_words, pending_word_len) = core::DivRem::div_rem( + len, BYTES_IN_BYTES31.try_into().unwrap() + ); + let mut chunk = 0; + let mut chunk_base = inner_byte_array_pointer(address, chunk); + let mut index_in_chunk = 0_u8; + let mut result: ByteArray = Default::default(); + loop { + if remaining_full_words == 0 { + break Result::Ok(()); + } + let value = + match starknet::syscalls::storage_read_syscall( + address_domain, storage_address_from_base_and_offset(chunk_base, index_in_chunk) + ) { + Result::Ok(value) => value, + Result::Err(err) => { break Result::Err(err); }, + }; + let value: bytes31 = match value.try_into() { + Option::Some(x) => x, + Option::None => { break Result::Err(array!['Invalid value']); }, + }; + result.data.append(value); + remaining_full_words -= 1; + index_in_chunk = match core::integer::u8_overflowing_add(index_in_chunk, 1) { + Result::Ok(x) => x, + Result::Err(_) => { + // After reading 256 `bytes31`s `index_in_chunk` will overflow and we move to the + // next chunk. + chunk += 1; + chunk_base = inner_byte_array_pointer(address, chunk); + 0 + }, + }; + }?; + if pending_word_len != 0 { + let pending_word = starknet::syscalls::storage_read_syscall( + address_domain, storage_address_from_base_and_offset(chunk_base, index_in_chunk) + )?; + result.pending_word = pending_word; + result.pending_word_len = pending_word_len; + } + Result::Ok(result) +} + +/// Writes a byte array to storage to domain `address_domain` and address `address`. +/// The length of the byte array is written to `address` at domain `address_domain`. +/// For more info read the documentation of `ByteArrayStore`. +fn inner_write_byte_array( + address_domain: u32, address: StorageAddress, value: ByteArray +) -> SyscallResult<()> { + let len = value.len(); + starknet::syscalls::storage_write_syscall(address_domain, address, len.into())?; + let mut full_words = value.data.span(); + let mut chunk = 0; + let mut chunk_base = inner_byte_array_pointer(address, chunk); + let mut index_in_chunk = 0_u8; + loop { + let curr_value = match full_words.pop_front() { + Option::Some(x) => x, + Option::None => { break Result::Ok(()); }, + }; + match starknet::syscalls::storage_write_syscall( + address_domain, + storage_address_from_base_and_offset(chunk_base, index_in_chunk), + (*curr_value).into() + ) { + Result::Ok(_) => {}, + Result::Err(err) => { break Result::Err(err); }, + }; + index_in_chunk = match core::integer::u8_overflowing_add(index_in_chunk, 1) { + Result::Ok(x) => x, + Result::Err(_) => { + // After writing 256 `byte31`s `index_in_chunk` will overflow and we move to the + // next chunk. + chunk += 1; + chunk_base = inner_byte_array_pointer(address, chunk); + 0 + }, + }; + }?; + if value.pending_word_len != 0 { + starknet::syscalls::storage_write_syscall( + address_domain, + storage_address_from_base_and_offset(chunk_base, index_in_chunk), + value.pending_word + )?; + } + Result::Ok(()) +} diff --git a/corelib/src/starknet/syscalls.cairo b/corelib/src/starknet/syscalls.cairo index 3585cbea2..bf785a90f 100644 --- a/corelib/src/starknet/syscalls.cairo +++ b/corelib/src/starknet/syscalls.cairo @@ -7,7 +7,7 @@ use starknet::{ // `address` - The address of the called contract. // `entry_point_selector` - A selector for a function within that contract. // `calldata` - Call arguments. -extern fn call_contract_syscall( +pub extern fn call_contract_syscall( address: ContractAddress, entry_point_selector: felt252, calldata: Span ) -> SyscallResult> implicits(GasBuiltin, System) nopanic; @@ -19,7 +19,7 @@ extern fn call_contract_syscall( // `deploy_from_zero` - Deploy the contract from the zero address. // // Returns the address of the deployed contract and the serialized return value of the constructor. -extern fn deploy_syscall( +pub extern fn deploy_syscall( class_hash: ClassHash, contract_address_salt: felt252, calldata: Span, @@ -29,22 +29,22 @@ extern fn deploy_syscall( // Emits an event. // `keys` - The keys of the event. // `data` - The data of the event. -extern fn emit_event_syscall( +pub extern fn emit_event_syscall( keys: Span, data: Span ) -> SyscallResult<()> implicits(GasBuiltin, System) nopanic; // Gets the block hash of the block with the given number. -extern fn get_block_hash_syscall( +pub extern fn get_block_hash_syscall( block_number: u64 ) -> SyscallResult implicits(GasBuiltin, System) nopanic; // Gets information about the current execution. -extern fn get_execution_info_syscall() -> SyscallResult< +pub extern fn get_execution_info_syscall() -> SyscallResult< Box > implicits(GasBuiltin, System) nopanic; // Gets information about the current execution, version 2. -extern fn get_execution_info_v2_syscall() -> SyscallResult< +pub extern fn get_execution_info_v2_syscall() -> SyscallResult< Box > implicits(GasBuiltin, System) nopanic; @@ -52,7 +52,7 @@ extern fn get_execution_info_v2_syscall() -> SyscallResult< // `class_hash` - The hash of the class you want to use. // `function_selector` - A selector for a function within that class. // `calldata` - Call arguments. -extern fn library_call_syscall( +pub extern fn library_call_syscall( class_hash: ClassHash, function_selector: felt252, calldata: Span ) -> SyscallResult> implicits(GasBuiltin, System) nopanic; @@ -60,7 +60,7 @@ extern fn library_call_syscall( // Sends a message to L1. // `to_address` - The recipient's L1 address. // `payload` - The content of the message. -extern fn send_message_to_l1_syscall( +pub extern fn send_message_to_l1_syscall( to_address: felt252, payload: Span ) -> SyscallResult<()> implicits(GasBuiltin, System) nopanic; @@ -69,7 +69,7 @@ extern fn send_message_to_l1_syscall( // in the future it will enable access to address spaces with different data availability // guarantees. // `address` - The address of the storage key to read. -extern fn storage_read_syscall( +pub extern fn storage_read_syscall( address_domain: u32, address: StorageAddress, ) -> SyscallResult implicits(GasBuiltin, System) nopanic; @@ -79,14 +79,14 @@ extern fn storage_read_syscall( // guarantees. // `address` - The address of the storage key to write. // `value` - The value to write to the key. -extern fn storage_write_syscall( +pub extern fn storage_write_syscall( address_domain: u32, address: StorageAddress, value: felt252 ) -> SyscallResult<()> implicits(GasBuiltin, System) nopanic; // Replaces the class hash of the current contract. // `class_hash` - The class hash that should replace the current one. -extern fn replace_class_syscall( +pub extern fn replace_class_syscall( class_hash: ClassHash ) -> SyscallResult<()> implicits(GasBuiltin, System) nopanic; @@ -94,6 +94,6 @@ extern fn replace_class_syscall( // Computes the keccak of the input. // The system call does not add any padding and the input needs to be a multiple of 1088 bits // (== 17 u64 word). -extern fn keccak_syscall( +pub extern fn keccak_syscall( input: Span ) -> SyscallResult implicits(GasBuiltin, System) nopanic; diff --git a/corelib/src/starknet/testing.cairo b/corelib/src/starknet/testing.cairo index 18d599606..68258b0a7 100644 --- a/corelib/src/starknet/testing.cairo +++ b/corelib/src/starknet/testing.cairo @@ -1,95 +1,92 @@ use starknet::ContractAddress; -use array::ArrayTrait; -use array::SpanTrait; -use traits::Into; +use core::array::ArrayTrait; +use core::array::SpanTrait; +use core::traits::Into; // A general cheatcode function used to simplify implementation of Starknet testing functions. // External users of the cairo crates can also implement their own cheatcodes // by injecting custom `CairoHintProcessor`. -extern fn cheatcode( +pub extern fn cheatcode( input: Span ) -> Span implicits() nopanic; // Set the block number to the provided value. -fn set_block_number(block_number: u64) { +pub fn set_block_number(block_number: u64) { cheatcode::<'set_block_number'>(array![block_number.into()].span()); } // Set the caller address to the provided value. -fn set_caller_address(address: ContractAddress) { +pub fn set_caller_address(address: ContractAddress) { cheatcode::<'set_caller_address'>(array![address.into()].span()); } // Set the contract address to the provided value. -fn set_contract_address(address: ContractAddress) { +pub fn set_contract_address(address: ContractAddress) { cheatcode::<'set_contract_address'>(array![address.into()].span()); } // Set the sequencer address to the provided value. -fn set_sequencer_address(address: ContractAddress) { +pub fn set_sequencer_address(address: ContractAddress) { cheatcode::<'set_sequencer_address'>(array![address.into()].span()); } // Set the block timestamp to the provided value. -fn set_block_timestamp(block_timestamp: u64) { +pub fn set_block_timestamp(block_timestamp: u64) { cheatcode::<'set_block_timestamp'>(array![block_timestamp.into()].span()); } // Set the version to the provided value. -fn set_version(version: felt252) { +pub fn set_version(version: felt252) { cheatcode::<'set_version'>(array![version].span()); } // Set the account contract address. -fn set_account_contract_address(address: ContractAddress) { +pub fn set_account_contract_address(address: ContractAddress) { cheatcode::<'set_account_contract_address'>(array![address.into()].span()); } // Set the max fee. -fn set_max_fee(fee: u128) { +pub fn set_max_fee(fee: u128) { cheatcode::<'set_max_fee'>(array![fee.into()].span()); } // Set the transaction hash. -fn set_transaction_hash(hash: felt252) { +pub fn set_transaction_hash(hash: felt252) { cheatcode::<'set_transaction_hash'>(array![hash].span()); } // Set the chain id. -fn set_chain_id(chain_id: felt252) { +pub fn set_chain_id(chain_id: felt252) { cheatcode::<'set_chain_id'>(array![chain_id].span()); } // Set the nonce. -fn set_nonce(nonce: felt252) { +pub fn set_nonce(nonce: felt252) { cheatcode::<'set_nonce'>(array![nonce].span()); } // Set the signature. -fn set_signature(signature: Span) { +pub fn set_signature(signature: Span) { cheatcode::<'set_signature'>(signature); } // Pop the earliest unpopped logged event for the contract. -fn pop_log_raw(address: ContractAddress) -> Option<(Span, Span)> { +pub fn pop_log_raw(address: ContractAddress) -> Option<(Span, Span)> { let mut log = cheatcode::<'pop_log'>(array![address.into()].span()); - Option::Some((serde::Serde::deserialize(ref log)?, serde::Serde::deserialize(ref log)?,)) + Option::Some((Serde::deserialize(ref log)?, Serde::deserialize(ref log)?,)) } // Pop the earliest unpopped logged event for the contract as the requested type. -fn pop_log>(address: ContractAddress) -> Option { +pub fn pop_log>(address: ContractAddress) -> Option { let (mut keys, mut data) = pop_log_raw(address)?; starknet::Event::deserialize(ref keys, ref data) } // TODO(Ilya): Decide if we limit the type of `to_address`. // Pop the earliest unpopped l2 to l1 message for the contract. -fn pop_l2_to_l1_message(address: ContractAddress) -> Option<(felt252, Span)> { +pub fn pop_l2_to_l1_message(address: ContractAddress) -> Option<(felt252, Span)> { let mut l2_to_l1_message = cheatcode::<'pop_l2_to_l1_message'>(array![address.into()].span()); Option::Some( - ( - serde::Serde::deserialize(ref l2_to_l1_message)?, - serde::Serde::deserialize(ref l2_to_l1_message)?, - ) + (Serde::deserialize(ref l2_to_l1_message)?, Serde::deserialize(ref l2_to_l1_message)?,) ) } diff --git a/corelib/src/string.cairo b/corelib/src/string.cairo index c22ea88f1..7368771d2 100644 --- a/corelib/src/string.cairo +++ b/corelib/src/string.cairo @@ -1 +1 @@ -trait StringLiteral; +pub trait StringLiteral; diff --git a/corelib/src/test.cairo b/corelib/src/test.cairo index 6f41b0f0b..84931a97b 100644 --- a/corelib/src/test.cairo +++ b/corelib/src/test.cairo @@ -1,17 +1,25 @@ mod array_test; mod bool_test; mod box_test; +mod byte_array_test; mod bytes31_test; mod cmp_test; mod dict_test; mod ec_test; mod felt_test; +mod fmt_test; mod hash_test; mod integer_test; mod keccak_test; +mod num_test; mod math_test; +mod nullable_test; +mod panics_test; mod plugins_test; +mod print_test; +mod result_test; mod secp256k1_test; mod secp256r1_test; mod test_utils; mod testing_test; +mod to_byte_array_test; diff --git a/corelib/src/test/array_test.cairo b/corelib/src/test/array_test.cairo index deb35401d..111aa6515 100644 --- a/corelib/src/test/array_test.cairo +++ b/corelib/src/test/array_test.cairo @@ -1,4 +1,4 @@ -use test::test_utils::{assert_eq, assert_ne}; +use core::test::test_utils::{assert_eq, assert_ne}; #[test] fn test_array() { @@ -23,7 +23,6 @@ fn test_array_out_of_bound_2() { } #[test] -#[available_gas(100000)] fn test_array_clone() { let felt252_snap_array: @Array = @array![10, 11, 12]; let felt252_snap_array_clone = felt252_snap_array.clone(); @@ -75,7 +74,6 @@ fn test_slice_out_of_bound_2() { } #[test] -#[available_gas(10000000)] fn test_equality() { let arr1 = array![]; let arr2 = array![10, 11, 12]; @@ -100,3 +98,49 @@ fn test_equality() { assert(arr3 != arr5, 'arr3 == arr5'); assert(arr4 != arr5, 'arr4 == arr5'); } + +#[test] +fn test_append() { + let mut arr = array![10, 11, 12]; + arr.append(13); + assert(arr.len() == 4, 'Unexpected length'); + assert_eq(arr[3], @13, 'Unexpected element'); +} + +#[test] +fn test_append_span() { + let mut arr = array![10, 11, 12]; + arr.append_span(arr.span()); + assert(arr.len() == 6, 'Unexpected length'); + assert_eq(arr[3], @10, 'Unexpected element'); + assert_eq(arr[4], @11, 'Unexpected element'); + assert_eq(arr[5], @12, 'Unexpected element'); +} + +mod felt252_span_from_tuple { + pub extern fn span_from_tuple(struct_like: Box<@T>) -> @Array nopanic; +} + +mod tuple_span_from_tuple { + pub extern fn span_from_tuple( + struct_like: Box<@T> + ) -> @Array<(felt252, felt252, felt252)> nopanic; +} + +#[test] +fn test_felt252_span_from_tuple() { + let span = felt252_span_from_tuple::span_from_tuple(BoxTrait::new(@(10, 20, 30))); + assert!(*span[0] == 10); + assert!(*span[1] == 20); + assert!(*span[2] == 30); +} + +#[test] +fn test_tuple_span_from_tuple() { + let multi_tuple = ((10, 20, 30), (40, 50, 60), (70, 80, 90)); + let span = tuple_span_from_tuple::span_from_tuple(BoxTrait::new(@multi_tuple)); + assert!(*span[0] == (10, 20, 30)); + assert!(*span[1] == (40, 50, 60)); + assert!(*span[2] == (70, 80, 90)); +} + diff --git a/corelib/src/test/bool_test.cairo b/corelib/src/test/bool_test.cairo index 881efb2b1..9cab5d677 100644 --- a/corelib/src/test/bool_test.cairo +++ b/corelib/src/test/bool_test.cairo @@ -1,4 +1,4 @@ -use test::test_utils::{assert_eq, assert_ne}; +use core::test::test_utils::{assert_eq, assert_ne}; #[test] fn test_bool_operators() { diff --git a/corelib/src/test/box_test.cairo b/corelib/src/test/box_test.cairo index 72349518c..d703e65ef 100644 --- a/corelib/src/test/box_test.cairo +++ b/corelib/src/test/box_test.cairo @@ -1,4 +1,4 @@ -use test::test_utils::{assert_eq, assert_ne}; +use core::test::test_utils::{assert_eq, assert_ne}; #[test] fn test_box_unbox_felt252s() { diff --git a/corelib/src/test/byte_array_test.cairo b/corelib/src/test/byte_array_test.cairo index ec70edd31..dd62b66f4 100644 --- a/corelib/src/test/byte_array_test.cairo +++ b/corelib/src/test/byte_array_test.cairo @@ -1,7 +1,6 @@ -use test::test_utils::{assert_eq, assert_ne}; +use core::test::test_utils::{assert_eq, assert_ne}; #[test] -#[available_gas(1000000)] fn test_append_byte() { let mut ba = Default::default(); let mut c = 1_u8; @@ -18,7 +17,6 @@ fn test_append_byte() { } #[test] -#[available_gas(10000000)] fn test_append_word() { let mut ba = Default::default(); @@ -50,7 +48,6 @@ fn test_append_word() { } #[test] -#[available_gas(1000000)] fn test_append() { let mut ba1 = test_byte_array_32(); let ba2 = test_byte_array_32(); @@ -66,7 +63,6 @@ fn test_append() { // Same as test_append, but with `+=` instead of `append`. #[test] -#[available_gas(1000000)] fn test_add_eq() { let mut ba1 = test_byte_array_32(); let ba2 = test_byte_array_32(); @@ -81,7 +77,6 @@ fn test_add_eq() { } #[test] -#[available_gas(1000000)] fn test_concat() { let ba1 = test_byte_array_32(); let ba2 = test_byte_array_32(); @@ -97,7 +92,6 @@ fn test_concat() { // Same as test_concat, but with `+` instead of `concat`. #[test] -#[available_gas(1000000)] fn test_add() { let ba1 = test_byte_array_32(); let ba2 = test_byte_array_32(); @@ -113,7 +107,6 @@ fn test_add() { // Test concat/append, first byte array empty. #[test] -#[available_gas(1000000)] fn test_concat_first_empty() { let ba1 = Default::default(); let ba2 = test_byte_array_32(); @@ -126,7 +119,6 @@ fn test_concat_first_empty() { // Test concat/append, second byte array empty. #[test] -#[available_gas(1000000)] fn test_concat_second_empty() { let ba1 = test_byte_array_32(); let ba2 = Default::default(); @@ -139,7 +131,6 @@ fn test_concat_second_empty() { // Test concat/append, first byte array pending word is empty. #[test] -#[available_gas(1000000)] fn test_concat_first_pending_0() { let ba1 = test_byte_array_31(); let ba2 = test_byte_array_32(); @@ -155,7 +146,6 @@ fn test_concat_first_pending_0() { // Test concat/append, second byte array pending word is empty. #[test] -#[available_gas(1000000)] fn test_concat_second_pending_0() { let ba1 = test_byte_array_32(); let ba2 = test_byte_array_31(); @@ -171,7 +161,6 @@ fn test_concat_second_pending_0() { // Test concat/append, split index of the words of the second byte array is 16. #[test] -#[available_gas(1000000)] fn test_concat_split_index_16() { let ba1 = test_byte_array_16(); let ba2 = test_byte_array_32(); @@ -184,7 +173,6 @@ fn test_concat_split_index_16() { // Test concat/append, split index of the words of the second byte array is < 16, specifically 1. #[test] -#[available_gas(1000000)] fn test_concat_split_index_lt_16() { let ba1 = test_byte_array_1(); let ba2 = test_byte_array_32(); @@ -197,7 +185,6 @@ fn test_concat_split_index_lt_16() { // Test concat/append, split index of the words of the second byte array is > 16, specifically 30. #[test] -#[available_gas(1000000)] fn test_concat_split_index_gt_16() { let ba1 = test_byte_array_30(); let ba2 = test_byte_array_33(); @@ -213,7 +200,6 @@ fn test_concat_split_index_gt_16() { // Sum of the lengths of the pending words of both byte arrays is 31 (a full word). #[test] -#[available_gas(1000000)] fn test_concat_pending_sum_up_to_full() { let ba1 = test_byte_array_32(); let ba2 = test_byte_array_30(); @@ -230,7 +216,6 @@ fn test_concat_pending_sum_up_to_full() { // Sum of the lengths of the pending words of both byte arrays is 31+16. // That is, the pending words aggregate to a full word, and the last split index is 16. #[test] -#[available_gas(1000000)] fn test_concat_pending_sum_up_to_more_than_word_16() { let ba1 = test_byte_array_17(); let ba2 = test_byte_array_30(); @@ -244,7 +229,6 @@ fn test_concat_pending_sum_up_to_more_than_word_16() { // Sum of the lengths of the pending words of both byte arrays is in [32, 31+15]. // That is, the pending words aggregate to a full word, and the last split index is <16. #[test] -#[available_gas(1000000)] fn test_concat_pending_sum_up_to_more_than_word_lt16() { let ba1 = test_byte_array_2(); let ba2 = test_byte_array_30(); @@ -258,7 +242,6 @@ fn test_concat_pending_sum_up_to_more_than_word_lt16() { // Sum of the lengths of the pending words of both byte arrays is >31+15 // That is, the pending words aggregate to a full word, and the last split index is >16. #[test] -#[available_gas(1000000)] fn test_concat_pending_sum_up_to_more_than_word_gt16() { let ba1 = test_byte_array_30(); let ba2 = test_byte_array_30(); @@ -272,7 +255,6 @@ fn test_concat_pending_sum_up_to_more_than_word_gt16() { } #[test] -#[available_gas(1000000)] fn test_len() { let ba: ByteArray = Default::default(); assert(ba.len() == 0, 'wrong ByteArray len'); @@ -285,7 +267,6 @@ fn test_len() { } #[test] -#[available_gas(100000000)] fn test_at_empty() { let ba: ByteArray = Default::default(); @@ -296,7 +277,6 @@ fn test_at_empty() { } #[test] -#[available_gas(100000000)] fn test_at() { let mut ba = test_byte_array_31(); ba.append(@test_byte_array_31()); @@ -324,7 +304,6 @@ fn test_at() { // Same as the previous test, but with [] instead of .at() (and without the out-of-bounds case). #[test] -#[available_gas(100000000)] fn test_index_view() { let mut ba = test_byte_array_31(); ba.append(@test_byte_array_31()); @@ -352,28 +331,26 @@ fn test_index_view() { // Test panic with [] in case of out-of-bounds #[test] #[should_panic(expected: ('Index out of bounds',))] -#[available_gas(100000000)] fn test_index_view_out_of_bounds() { let mut ba = test_byte_array_31(); ba.append(@test_byte_array_31()); ba.append(@test_byte_array_17()); - let x = ba[79]; + let _x = ba[79]; } #[test] fn test_string_literals() { - let ba: ByteArray = "12345"; // len < 16 - let ba: ByteArray = "1234567890123456"; // len == 16 - let ba: ByteArray = "123456789012345678"; // 16 < len < 31 - let ba: ByteArray = "1234567890123456789012345678901"; // len == 31 - let ba: ByteArray = "123456789012345678901234567890123"; // 31 < len < 47 - let ba: ByteArray = "12345678901234567890123456789012345678901234567"; // len == 47 - let ba: ByteArray = "123456789012345678901234567890123456789012345678"; // len > 47 + let _ba: ByteArray = "12345"; // len < 16 + let _ba: ByteArray = "1234567890123456"; // len == 16 + let _ba: ByteArray = "123456789012345678"; // 16 < len < 31 + let _ba: ByteArray = "1234567890123456789012345678901"; // len == 31 + let _ba: ByteArray = "123456789012345678901234567890123"; // 31 < len < 47 + let _ba: ByteArray = "12345678901234567890123456789012345678901234567"; // len == 47 + let _ba: ByteArray = "123456789012345678901234567890123456789012345678"; // len > 47 } #[test] -#[available_gas(100000000)] fn test_equality() { let byte_array: ByteArray = "a"; assert(@byte_array == @"a", 'Same strings are not equal'); @@ -402,7 +379,6 @@ fn test_equality() { } #[test] -#[available_gas(100000000)] fn test_reverse() { // Arrays of length < 16 let ba: ByteArray = "abc"; @@ -468,9 +444,38 @@ fn test_reverse() { assert_eq(@palindrome, @palindrome.rev(), 'palindrome is not a palindrome'); } +#[test] +fn test_serde() { + let mut serialized = array![]; + let ba: ByteArray = ""; + let expected_serialized = array![0, 0, 0]; + ba.serialize(ref serialized); + compare_spans(serialized.span(), expected_serialized.span()); + + let mut serialized = array![]; + let ba: ByteArray = "hello"; + let expected_serialized = array![ + 0, // data len + 0x68656c6c6f, // pending_word + 5 // pending_word_len + ]; + ba.serialize(ref serialized); + compare_spans(serialized.span(), expected_serialized.span()); + + let mut serialized = array![]; + let ba: ByteArray = "Long string, more than 31 characters."; + let expected_serialized = array![ + 1, // data len + 0x4c6f6e6720737472696e672c206d6f7265207468616e203331206368617261, // data + 0x63746572732e, // pending_word + 6 // pending_word_len + ]; + ba.serialize(ref serialized); + compare_spans(serialized.span(), expected_serialized.span()); +} + // ========= Test helper functions ========= -use debug::PrintTrait; fn compare_byte_array( mut ba: @ByteArray, mut data: Span, pending_word_len: usize, pending_word: felt252 ) { @@ -483,37 +488,33 @@ fn compare_byte_array( Option::Some(x) => { let actual_word = (*x).into(); let expected_word = *data.pop_front().unwrap(); - if actual_word != expected_word { - 'data_index:'.print(); - data_index.print(); - 'expected word:'.print(); - expected_word.print(); - 'actual word:'.print(); - actual_word.print(); - - panic_with_felt252('wrong data'); - } + assert_eq!(actual_word, expected_word, "wrong data for index: {data_index}"); }, Option::None(_) => { break; } } data_index += 1; }; - if *ba.pending_word_len != pending_word_len { - 'expected pending word len:'.print(); - pending_word_len.print(); - 'actual pending word len:'.print(); - (*ba.pending_word_len).print(); - panic_with_felt252('wrong pending_word_len'); - } + assert_eq!(*ba.pending_word_len, pending_word_len); let ba_pending_word_felt: felt252 = (*ba.pending_word).into(); - if ba_pending_word_felt != pending_word { - 'expected pending word:'.print(); - pending_word.print(); - 'actual pending word:'.print(); - ba_pending_word_felt.print(); - panic_with_felt252('wrong pending_word'); - } + assert_eq!(ba_pending_word_felt, pending_word); +} + +fn compare_spans, +PartialEq, +Copy, +Drop>( + mut a: Span, mut b: Span +) { + assert_eq!(a.len(), b.len()); + let mut index = 0; + loop { + match a.pop_front() { + Option::Some(current_a) => { + let current_b = b.pop_front().unwrap(); + assert_eq!(*current_a, *current_b, "wrong data for index: {index}"); + }, + Option::None(_) => { break; } + } + index += 1; + }; } fn test_byte_array_1() -> ByteArray { diff --git a/corelib/src/test/bytes31_test.cairo b/corelib/src/test/bytes31_test.cairo index 825300cea..9176c2b56 100644 --- a/corelib/src/test/bytes31_test.cairo +++ b/corelib/src/test/bytes31_test.cairo @@ -1,52 +1,52 @@ -use bytes_31::split_bytes31; +use core::bytes_31::{split_bytes31, bytes31_const}; const POW_2_248: felt252 = 0x100000000000000000000000000000000000000000000000000000000000000; #[test] fn test_at() { let b1 = bytes31_const::<0x01>(); - assert(b1.at(0) == 0x01, 'wrong byte at index 0'); + assert_eq!(b1.at(0), 0x01); let b17 = bytes31_const::<0x0102030405060708090a0b0c0d0e0f1011>(); - assert(b17.at(0) == 0x11, 'wrong byte at index 0'); - assert(b17.at(1) == 0x10, 'wrong byte at index 1'); - assert(b17.at(2) == 0x0f, 'wrong byte at index 2'); - assert(b17.at(14) == 0x03, 'wrong byte at index 14'); - assert(b17.at(15) == 0x02, 'wrong byte at index 15'); - assert(b17.at(16) == 0x01, 'wrong byte at index 16'); + assert_eq!(b17.at(0), 0x11); + assert_eq!(b17.at(1), 0x10); + assert_eq!(b17.at(2), 0x0f); + assert_eq!(b17.at(14), 0x03); + assert_eq!(b17.at(15), 0x02); + assert_eq!(b17.at(16), 0x01); let b31 = bytes31_const::<0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f>(); - assert(b31.at(0) == 0x1f, 'wrong byte at index 0'); - assert(b31.at(1) == 0x1e, 'wrong byte at index 1'); - assert(b31.at(2) == 0x1d, 'wrong byte at index 2'); - assert(b31.at(14) == 0x11, 'wrong byte at index 14'); - assert(b31.at(15) == 0x10, 'wrong byte at index 15'); - assert(b31.at(16) == 0x0f, 'wrong byte at index 16'); - assert(b31.at(17) == 0x0e, 'wrong byte at index 17'); - assert(b31.at(29) == 0x02, 'wrong byte at index 29'); - assert(b31.at(30) == 0x01, 'wrong byte at index 30'); + assert_eq!(b31.at(0), 0x1f); + assert_eq!(b31.at(1), 0x1e); + assert_eq!(b31.at(2), 0x1d); + assert_eq!(b31.at(14), 0x11); + assert_eq!(b31.at(15), 0x10); + assert_eq!(b31.at(16), 0x0f); + assert_eq!(b31.at(17), 0x0e); + assert_eq!(b31.at(29), 0x02); + assert_eq!(b31.at(30), 0x01); } // Same as the previous test, but with [] instead of .at() #[test] fn test_index_view() { let b1 = bytes31_const::<0x01>(); - assert(b1[0] == 0x01, 'wrong byte at index 0'); + assert_eq!(b1[0], 0x01); let b17 = bytes31_const::<0x0102030405060708090a0b0c0d0e0f1011>(); - assert(b17[0] == 0x11, 'wrong byte at index 0'); - assert(b17[1] == 0x10, 'wrong byte at index 1'); - assert(b17[2] == 0x0f, 'wrong byte at index 2'); - assert(b17[14] == 0x03, 'wrong byte at index 14'); - assert(b17[15] == 0x02, 'wrong byte at index 15'); - assert(b17[16] == 0x01, 'wrong byte at index 16'); + assert_eq!(b17[0], 0x11); + assert_eq!(b17[1], 0x10); + assert_eq!(b17[2], 0x0f); + assert_eq!(b17[14], 0x03); + assert_eq!(b17[15], 0x02); + assert_eq!(b17[16], 0x01); let b31 = bytes31_const::<0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f>(); - assert(b31[0] == 0x1f, 'wrong byte at index 0'); - assert(b31[1] == 0x1e, 'wrong byte at index 1'); - assert(b31[2] == 0x1d, 'wrong byte at index 2'); - assert(b31[14] == 0x11, 'wrong byte at index 14'); - assert(b31[15] == 0x10, 'wrong byte at index 15'); + assert_eq!(b31[0], 0x1f); + assert_eq!(b31[1], 0x1e); + assert_eq!(b31[2], 0x1d); + assert_eq!(b31[14], 0x11); + assert_eq!(b31[15], 0x10); assert(b31[16] == 0x0f, 'wrong byte at index 16'); assert(b31[17] == 0x0e, 'wrong byte at index 17'); assert(b31[29] == 0x02, 'wrong byte at index 29'); diff --git a/corelib/src/test/cmp_test.cairo b/corelib/src/test/cmp_test.cairo index 91e964aa2..2b21155fd 100644 --- a/corelib/src/test/cmp_test.cairo +++ b/corelib/src/test/cmp_test.cairo @@ -1,5 +1,5 @@ -use cmp::{max, min}; -use test::test_utils::{assert_eq, assert_ne}; +use core::cmp::{max, min}; +use core::test::test_utils::{assert_eq, assert_ne}; // Integer tests diff --git a/corelib/src/test/dict_test.cairo b/corelib/src/test/dict_test.cairo index ff3c1eb0c..bee920c52 100644 --- a/corelib/src/test/dict_test.cairo +++ b/corelib/src/test/dict_test.cairo @@ -1,5 +1,6 @@ -use dict::Felt252DictEntryTrait; -use test::test_utils::{assert_eq, assert_ne}; +use core::dict::Felt252DictEntryTrait; +use core::test::test_utils::{assert_eq, assert_ne}; +use core::nullable; #[test] fn test_dict_new() -> Felt252Dict { @@ -9,14 +10,14 @@ fn test_dict_new() -> Felt252Dict { #[test] fn test_dict_squash_empty() { let mut dict: Felt252Dict = Default::default(); - let squashed_dict = dict.squash(); + let _squashed_dict = dict.squash(); } #[test] fn test_dict_default_val() { let mut dict: Felt252Dict = Default::default(); let default_val = dict.get(0); - assert_eq(@default_val, @0, 'default_val == 0'); + assert_eq!(default_val, 0); } #[test] @@ -27,9 +28,9 @@ fn test_dict_write_read() { let val10 = dict[10]; let val11 = dict[11]; let val12 = dict[12]; - assert_eq(@val10, @110, 'dict[10] == 110'); - assert_eq(@val11, @111, 'dict[11] == 111'); - assert_eq(@val12, @0, 'default_val == 0'); + assert_eq!(val10, 110); + assert_eq!(val11, 111); + assert_eq!(val12, 0); } #[test] @@ -37,18 +38,18 @@ fn test_dict_entry() { let mut dict = Default::default(); dict.insert(10, 110); let (entry, value) = dict.entry(10); - assert_eq(@value, @110, 'dict[10] == 110'); + assert_eq!(value, 110); let mut dict = entry.finalize(11); - assert_eq(@dict[10], @11, 'dict[10] == 11'); + assert_eq!(dict[10], 11); } #[test] fn test_dict_entry_uninitialized() { let mut dict = Default::default(); let (entry, value) = dict.entry(10); - assert_eq(@value, @0_felt252, 'dict[10] == 0'); + assert_eq!(value, 0_felt252); let mut dict = entry.finalize(110); - assert_eq(@dict[10], @110, 'dict[10] == 110'); + assert_eq!(dict[10], 110); } #[test] @@ -56,11 +57,11 @@ fn test_dict_update_twice() { let mut dict = Default::default(); dict.insert(10, 110); let (entry, value) = dict.entry(10); - assert_eq(@value, @110, 'dict[10] == 110'); + assert_eq!(value, 110); dict = entry.finalize(11); - assert_eq(@dict[10], @11, 'dict[10] == 11'); + assert_eq!(dict[10], 11); let (entry, value) = dict.entry(10); - assert_eq(@value, @11, 'dict[10] == 11'); + assert_eq!(value, 11); dict = entry.finalize(12); assert_eq(@dict[10], @12, 'dict[10] == 12'); } @@ -73,7 +74,7 @@ fn test_dict_update_twice() { fn test_dict_entry_destruct() { let mut dict = Default::default(); dict.insert(10, 110); - let (entry, value) = dict.entry(10); + let (_entry, _value) = dict.entry(10); } const KEY1: felt252 = 10; @@ -107,8 +108,8 @@ fn test_dict_big_keys() { #[test] fn test_dict_of_nullable() { let mut dict = Default::default(); - dict.insert(10, nullable_from_box(BoxTrait::new(1))); - dict.insert(11, nullable_from_box(BoxTrait::new(2))); + dict.insert(10, nullable::nullable_from_box(BoxTrait::new(1))); + dict.insert(11, nullable::nullable_from_box(BoxTrait::new(2))); let val10 = dict[10].deref(); let val11 = dict[11].deref(); let val12 = dict[12]; @@ -122,15 +123,28 @@ fn test_dict_of_nullable() { 'default_val == null' ); } -// TODO(lior): Re-enable the test once Dict of bools are supported. -// #[test] -// fn test_bool_dict() { -// let mut bool_dict: Felt252Dict = Felt252DictTrait::new(); -// let squashed_dict = bool_dict.squash(); -// let mut bool_dict: Felt252Dict = Felt252DictTrait::new(); -// assert(!bool_dict.get(0), 'default_val != false'); -// bool_dict.insert(1, true); -// assert(bool_dict.get(1), 'bool_dict[1] != true'); -// } +#[test] +fn test_bool_dict() { + let mut bool_dict: Felt252Dict = Default::default(); + let _squashed_dict = bool_dict.squash(); + let mut bool_dict: Felt252Dict = Default::default(); + assert(!bool_dict.get(0), 'default_val != false'); + bool_dict.insert(1, true); + assert(bool_dict.get(1), 'bool_dict[1] != true'); +} + +#[test] +fn test_array_dict() { + let mut dict = Default::default(); + dict.insert(10, NullableTrait::new(array![1, 2, 3])); + let (entry, value) = dict.entry(10); + assert_eq(@value.deref(), @array![1, 2, 3], 'dict[10] == [1, 2, 3]'); + dict = entry.finalize(NullableTrait::new(array![4, 5])); + let (entry, value) = dict.entry(10); + assert_eq(@value.deref(), @array![4, 5], 'dict[10] == [4, 5]'); + dict = entry.finalize(nullable::null()); + let (_entry, value) = dict.entry(10); + assert(value.is_null(), 'dict[10] == null'); +} diff --git a/corelib/src/test/ec_test.cairo b/corelib/src/test/ec_test.cairo index e6fc0b4bd..249522a93 100644 --- a/corelib/src/test/ec_test.cairo +++ b/corelib/src/test/ec_test.cairo @@ -1,7 +1,8 @@ -use ec::{EcPointTrait, EcPointTryIntoNonZero, EcStateTrait}; -use option::OptionTrait; -use test::test_utils::{assert_eq, assert_ne}; -use traits::{Into, TryInto}; +use core::ec::{EcPoint, EcPointTrait, EcStateTrait}; +use core::ecdsa; +use core::option::OptionTrait; +use core::test::test_utils::{assert_eq, assert_ne}; +use core::traits::{Into, TryInto}; #[test] #[should_panic] @@ -111,7 +112,6 @@ fn test_ecdsa() { } #[test] -#[available_gas(100000000)] fn test_ecdsa_recover_public_key() { let message_hash = 0x503f4bea29baee10b22a7f10bdc82dda071c977c1f25b8f3973d34e6b03b2c; let signature_r = 0xbe96d72eb4f94078192c2e84d5230cde2a70f4b45c8797e2c907acff5060bb; diff --git a/corelib/src/test/felt_test.cairo b/corelib/src/test/felt_test.cairo index 52b65af34..1276e8c96 100644 --- a/corelib/src/test/felt_test.cairo +++ b/corelib/src/test/felt_test.cairo @@ -1,4 +1,4 @@ -use test::test_utils::{assert_eq, assert_ne}; +use core::test::test_utils::{assert_eq, assert_ne}; #[test] fn test_felt252_operators() { diff --git a/corelib/src/test/fmt_test.cairo b/corelib/src/test/fmt_test.cairo new file mode 100644 index 000000000..57fabbf2d --- /dev/null +++ b/corelib/src/test/fmt_test.cairo @@ -0,0 +1,80 @@ +#[test] +fn test_format() { + let ba: ByteArray = "hello"; + assert(format!("{}", ba) == ba, 'byte array bad formatting'); + assert(format!("{}", 97_felt252) == "97", 'felt252 bad formatting'); + assert(format!("{}", 97_usize) == "97", 'usize bad formatting'); + assert(format!("{}", 34 - 5) == "29", 'expression bad formatting'); + assert(format!("no_format") == "no_format", 'no args bad formatting'); + assert(format!("{}{}", 12_usize, 14_u32) == "1214", 'two args bad formatting'); + assert(format!("{0}{0}", 12_usize) == "1212", 'positional bad formatting'); + assert(format!("{}{1}", 12_usize, 14_u32) == "1214", 'positional mix bad formatting'); + assert(format!("{ba}_{}_{}_{1}", 12, 14_u32) == "hello_12_14_14", 'full mix bad formatting'); + assert(format!("{{{{}}}}") == "{{}}", 'special cases bad formatting'); + let nz_value: NonZero = 1.try_into().unwrap(); + assert(format!("{}", nz_value) == "1", 'non zero bad formatting'); +} + +#[derive(Debug, Drop)] +struct StructExample { + felt_value: felt252, + bool_value: bool, + byte_array_value: ByteArray, + enum_value: EnumExample, +} + +#[derive(Debug, Drop)] +enum EnumExample { + Empty, + FeltValue: felt252, + BoolValue: bool, +} + +#[test] +fn test_format_debug() { + let ba: ByteArray = "hello"; + assert(format!("{:?}", ba) == "\"hello\"", 'byte array bad formatting'); + assert(format!("{:?}", 97_felt252) == "97", 'felt252 bad formatting'); + assert(format!("{:?}", 97_usize) == "97", 'usize bad formatting'); + assert(format!("{:?}{:?}", 12_usize, 14_u32) == "1214", 'two args bad formatting'); + assert(format!("{0:?}{0:?}", 12_usize) == "1212", 'positional bad formatting'); + assert(format!("{:?}{1:?}", 12_usize, 14_u32) == "1214", 'positional mix bad formatting'); + assert( + format!("{ba:?}_{:?}_{:?}_{1:?}", 12, 14_u32) == "\"hello\"_12_14_14", + 'full mix bad formatting' + ); + assert( + format!("{:?}", EnumExample::Empty) == "EnumExample::Empty(())", 'bad enum empty derive fmt' + ); + assert( + format!("{:?}", EnumExample::FeltValue(4)) == "EnumExample::FeltValue(4)", + 'bad derive enum fmt' + ); + assert( + format!( + "{:?}", + StructExample { + felt_value: 6, + bool_value: false, + byte_array_value: "ByteArray", + enum_value: EnumExample::BoolValue(true) + } + ) == "StructExample { felt_value: 6, bool_value: false, byte_array_value: \"ByteArray\", enum_value: EnumExample::BoolValue(true) }", + 'bad derive struct formatting' + ); + assert( + format!("{:?}", ((), (1,), (2, 3), (4, 5, 6))) == "((), (1,), (2, 3), (4, 5, 6))", + 'bad tuple fmt' + ); + assert(format!("{:?}", core::box::BoxTrait::new(1)) == "&1", 'bad box fmt'); + assert( + format!("{:?}", core::nullable::NullableTrait::new(1)) == "&1", 'bad nullable value fmt' + ); + assert(format!("{:?}", core::nullable::null::()) == "null", 'bad null fmt'); +} + +#[test] +fn test_array_debug() { + let arr = array![1, 2, 3]; + assert(format!("{:?}", arr) == "[1, 2, 3]", 'bad array fmt'); +} diff --git a/corelib/src/test/hash_test.cairo b/corelib/src/test/hash_test.cairo index 75b83ae85..93f9eb965 100644 --- a/corelib/src/test/hash_test.cairo +++ b/corelib/src/test/hash_test.cairo @@ -1,11 +1,11 @@ -use test::test_utils::{assert_eq, assert_ne}; -use hash::{HashStateTrait, HashStateExTrait}; -use poseidon::PoseidonTrait; +use core::test::test_utils::{assert_eq, assert_ne}; +use core::hash::{HashStateTrait, HashStateExTrait}; +use core::poseidon::PoseidonTrait; #[test] fn test_pedersen_hash() { assert_eq( - @pedersen::pedersen(1, 2), + @core::pedersen::pedersen(1, 2), @2592987851775965742543459319508348457290966253241455514226127639100457844774, 'Wrong hash value' ); @@ -13,7 +13,7 @@ fn test_pedersen_hash() { #[test] fn test_poseidon_hades_permutation() { - let (s0, s1, s2) = poseidon::hades_permutation(1, 2, 3); + let (s0, s1, s2) = core::poseidon::hades_permutation(1, 2, 3); assert_eq( @s0, @442682200349489646213731521593476982257703159825582578145778919623645026501, @@ -32,18 +32,17 @@ fn test_poseidon_hades_permutation() { } #[test] -#[available_gas(300000)] fn test_poseidon_hash_span() { // Test odd number of inputs. assert_eq( - @poseidon::poseidon_hash_span(array![1, 2, 3].span()), + @core::poseidon::poseidon_hash_span(array![1, 2, 3].span()), @0x2f0d8840bcf3bc629598d8a6cc80cb7c0d9e52d93dab244bbf9cd0dca0ad082, 'wrong result' ); // Test even number of inputs. assert_eq( - @poseidon::poseidon_hash_span(array![1, 2, 3, 4].span()), + @core::poseidon::poseidon_hash_span(array![1, 2, 3, 4].span()), @0x26e3ad8b876e02bc8a4fc43dad40a8f81a6384083cabffa190bcf40d512ae1d, 'wrong result' ); diff --git a/corelib/src/test/integer_test.cairo b/corelib/src/test/integer_test.cairo index bba6c5273..14633854e 100644 --- a/corelib/src/test/integer_test.cairo +++ b/corelib/src/test/integer_test.cairo @@ -1,8 +1,11 @@ -use integer::{ - BoundedInt, u128_wrapping_sub, u16_sqrt, u32_sqrt, u64_sqrt, u8_sqrt, u512, u256_wide_mul, - u256_as_non_zero, u512_safe_div_rem_by_u256, u128_as_non_zero +use core::{ + integer, + integer::{ + BoundedInt, u128_sqrt, u128_wrapping_sub, u16_sqrt, u256_sqrt, u256_wide_mul, u32_sqrt, + u512_safe_div_rem_by_u256, u512, u64_sqrt, u8_sqrt + } }; -use test::test_utils::{assert_eq, assert_ne, assert_le, assert_lt, assert_gt, assert_ge}; +use core::test::test_utils::{assert_eq, assert_ne, assert_le, assert_lt, assert_gt, assert_ge}; #[test] fn test_u8_operators() { @@ -97,7 +100,7 @@ fn test_u8_mul_overflow_3() { } #[test] -#[should_panic] +#[should_panic(expected: ('Division by 0',))] fn test_u8_div_by_0() { 2_u8 / 0_u8; } @@ -200,7 +203,7 @@ fn test_u16_mul_overflow_3() { } #[test] -#[should_panic] +#[should_panic(expected: ('Division by 0',))] fn test_u16_div_by_0() { 2_u16 / 0_u16; } @@ -303,7 +306,7 @@ fn test_u32_mul_overflow_3() { } #[test] -#[should_panic] +#[should_panic(expected: ('Division by 0',))] fn test_u32_div_by_0() { 2_u32 / 0_u32; } @@ -408,7 +411,7 @@ fn test_u64_mul_overflow_3() { } #[test] -#[should_panic] +#[should_panic(expected: ('Division by 0',))] fn test_u64_div_by_0() { 2_u64 / 0_u64; } @@ -558,7 +561,7 @@ fn test_u128_mul_overflow_3() { } #[test] -#[should_panic] +#[should_panic(expected: ('Division by 0',))] fn test_u128_div_by_0() { 2_u128 / 0_u128; } @@ -908,7 +911,6 @@ fn test_u256_sqrt() { #[test] fn test_u256_try_into_felt252() { - let FELT252_PRIME = 0x800000000000011000000000000000000000000000000000000000000000001_u256; assert_eq(@1_u256.try_into().unwrap(), @1_felt252, '1 == 1'_felt252); assert_eq( @0x800000000000011000000000000000000000000000000000000000000000000_u256.try_into().unwrap(), @@ -931,39 +933,211 @@ fn test_u256_try_into_felt252() { assert(f.is_none(), 'prime+2**128 is not felt252'); } -fn cast_must_pass< +/// Checks if `b` is out of range of `A`. +fn is_out_of_range, +TryInto>(b: B) -> bool { + let no_a: Option = b.try_into(); + no_a.is_none() +} + +/// Checks if `SubType` is trivially castable to `SuperType`. +fn cast_subtype_valid< + SubType, + SuperType, + +Drop, + +Drop, + +Copy, + +Copy, + +BoundedInt, + +PartialEq, + +PartialEq, + +Into, + +TryInto +>() -> bool { + let max_sub: SubType = BoundedInt::max(); + let max_sub_as_super: SuperType = max_sub.into(); + let min_sub: SubType = BoundedInt::min(); + let min_sub_as_super: SuperType = min_sub.into(); + min_sub_as_super.try_into().unwrap() == min_sub + && max_sub_as_super.try_into().unwrap() == max_sub +} + +/// Checks that `A::max()` is castable to `B`, and `A::max() + 1` is in `B`s range, and not +/// castable back to `A`. +fn validate_max_strictly_contained< A, B, +Drop, +Drop, + +Copy, +Copy, + +Add, + +BoundedInt, + +PartialEq, + +PartialEq, + +TryInto, + +TryInto, + +TryInto +>( + err: felt252 +) { + let max_a: A = BoundedInt::max(); + let max_a_as_b: B = max_a.try_into().expect(err); + assert(Option::Some(max_a) == max_a_as_b.try_into(), err); + assert(is_out_of_range::(max_a_as_b + 1.try_into().unwrap()), err); +} + +/// Checks that `A::min()` is castable to `B`, and `A::min() - 1` is in `B`s range, and not +/// castable back to `A`. +fn validate_min_strictly_contained< + A, + B, + +Drop, + +Drop, +Copy, + +Copy, + +Sub, + +BoundedInt, +PartialEq, +PartialEq, + +TryInto, + +TryInto, + +TryInto +>( + err: felt252 +) { + let min_sub: A = BoundedInt::min(); + let min_sub_as_super: B = min_sub.try_into().expect(err); + assert(Option::Some(min_sub) == min_sub_as_super.try_into(), err); + assert(is_out_of_range::(min_sub_as_super - 1.try_into().unwrap()), err); +} + +/// Checks that castings from `SubType` to `SuperType` are correct around the bounds, where +/// `SubType` is strictly contained (in both bounds) in `SuperType`. +fn validate_cast_bounds_strictly_contained< + SubType, + SuperType, + +Drop, + +Drop, + +Copy, + +Copy, + +Add, + +Sub, + +BoundedInt, + +PartialEq, + +PartialEq, + +Into, + +TryInto, + +TryInto +>( + err: felt252 +) { + assert(cast_subtype_valid::(), err); + validate_min_strictly_contained::(err); + validate_max_strictly_contained::(err); +} + +/// Checks that castings from `SubType` to `SuperType` are correct around the bounds, where +/// `SubType` has the same min as `SuperType`, but has a lower max. +fn validate_cast_bounds_contained_same_min< + SubType, + SuperType, + +Drop, + +Drop, + +Copy, + +Copy, + +Add, + +Sub, + +BoundedInt, + +BoundedInt, + +PartialEq, + +PartialEq, + +Into, + +TryInto, + +TryInto +>( + err: felt252 +) { + assert(cast_subtype_valid::(), err); + assert(BoundedInt::::min().into() == BoundedInt::::min(), err); + validate_max_strictly_contained::(err); +} + +/// Checks that castings from `A` to `B` are correct around the bounds. +/// Assumes that the ordering of the bounds is: `a_min < b_min < a_max < b_max`. +fn validate_cast_bounds_overlapping< + A, + B, + +Drop, + +Drop, + +Copy, + +Copy, + +Sub, + +Add, +BoundedInt, +BoundedInt, - +Into, - +TryInto + +PartialEq, + +PartialEq, + +TryInto, + +TryInto, + +TryInto, + +TryInto >( - ui: A, uj: B -) -> bool { - uj == ui.into() - && ui == uj.try_into().unwrap() - && BoundedInt::::min() == BoundedInt::::min().into() - && BoundedInt::::min() == BoundedInt::::min().try_into().unwrap() + err: felt252 +) { + validate_min_strictly_contained::(err); + validate_max_strictly_contained::(err); } + #[test] fn proper_cast() { - assert(cast_must_pass(0xFF_u8, 0xFF_u16), 'u8 to_and_fro u16'); - assert(cast_must_pass(0xFF_u8, 0xFF_u32), 'u8 to_and_fro u32'); - assert(cast_must_pass(0xFF_u8, 0xFF_u64), 'u8 to_and_fro u64'); - assert(cast_must_pass(0xFF_u8, 0xFF_u128), 'u8 to_and_fro u128'); - assert(cast_must_pass(0xFFFF_u16, 0xFFFF_u32), 'u16 to_and_fro u32'); - assert(cast_must_pass(0xFFFF_u16, 0xFFFF_u64), 'u16 to_and_fro u64'); - assert(cast_must_pass(0xFFFF_u16, 0xFFFF_u128), 'u16 to_and_fro u128'); - assert(cast_must_pass(0xFFFFFFFF_u32, 0xFFFFFFFF_u64), 'u32 to_and_fro u64'); - assert(cast_must_pass(0xFFFFFFFF_u32, 0xFFFFFFFF_u128), 'u32 to_and_fro u128'); - assert(cast_must_pass(0xFFFFFFFFFFFFFFFF_u64, 0xFFFFFFFFFFFFFFFF_u128), 'u64 to_and_fro u128'); + validate_cast_bounds_contained_same_min::('u8 u16 casts'); + validate_cast_bounds_contained_same_min::('u8 u32 casts'); + validate_cast_bounds_contained_same_min::('u8 u64 casts'); + validate_cast_bounds_contained_same_min::('u8 u128 casts'); + validate_cast_bounds_contained_same_min::('u16 u32 casts'); + validate_cast_bounds_contained_same_min::('u16 u64 casts'); + validate_cast_bounds_contained_same_min::('u16 u128 casts'); + validate_cast_bounds_contained_same_min::('u32 u64 casts'); + validate_cast_bounds_contained_same_min::('u32 u128 casts'); + validate_cast_bounds_contained_same_min::('u64 u128 casts'); + + validate_cast_bounds_strictly_contained::('u8 i16 casts'); + validate_cast_bounds_strictly_contained::('u8 i32 casts'); + validate_cast_bounds_strictly_contained::('u8 i64 casts'); + validate_cast_bounds_strictly_contained::('u8 i128 casts'); + validate_cast_bounds_strictly_contained::('u16 i32 casts'); + validate_cast_bounds_strictly_contained::('u16 i64 casts'); + validate_cast_bounds_strictly_contained::('u16 i128 casts'); + validate_cast_bounds_strictly_contained::('u32 i64 casts'); + validate_cast_bounds_strictly_contained::('u32 i128 casts'); + validate_cast_bounds_strictly_contained::('u64 i128 casts'); + + validate_cast_bounds_strictly_contained::('i8 i16 casts'); + validate_cast_bounds_strictly_contained::('i8 i32 casts'); + validate_cast_bounds_strictly_contained::('i8 i64 casts'); + validate_cast_bounds_strictly_contained::('i8 i128 casts'); + validate_cast_bounds_strictly_contained::('i16 i32 casts'); + validate_cast_bounds_strictly_contained::('i16 i64 casts'); + validate_cast_bounds_strictly_contained::('i16 i128 casts'); + validate_cast_bounds_strictly_contained::('i32 i64 casts'); + validate_cast_bounds_strictly_contained::('i32 i128 casts'); + validate_cast_bounds_strictly_contained::('i64 i128 casts'); + + validate_cast_bounds_overlapping::('i8 u8 casts'); + validate_cast_bounds_overlapping::('i8 u16 casts'); + validate_cast_bounds_overlapping::('i8 u32 casts'); + validate_cast_bounds_overlapping::('i8 u64 casts'); + validate_cast_bounds_overlapping::('i8 u128 casts'); + validate_cast_bounds_overlapping::('i16 u16 casts'); + validate_cast_bounds_overlapping::('i16 u32 casts'); + validate_cast_bounds_overlapping::('i16 u64 casts'); + validate_cast_bounds_overlapping::('i16 u128 casts'); + validate_cast_bounds_overlapping::('i32 u32 casts'); + validate_cast_bounds_overlapping::('i32 u64 casts'); + validate_cast_bounds_overlapping::('i32 u128 casts'); + validate_cast_bounds_overlapping::('i64 u64 casts'); + validate_cast_bounds_overlapping::('i64 u128 casts'); + validate_cast_bounds_overlapping::('i128 u128 casts'); } #[test] @@ -988,124 +1162,124 @@ fn test_into_self_type() { #[test] #[should_panic] fn panic_u16_u8_1() { - let out: u8 = (0xFF_u16 + 1_u16).try_into().unwrap(); + let _out: u8 = (0xFF_u16 + 1_u16).try_into().unwrap(); } #[test] #[should_panic] fn panic_u16_u8_2() { let max_u16: u16 = 0xFFFF; - let out: u8 = max_u16.try_into().unwrap(); + let _out: u8 = max_u16.try_into().unwrap(); } #[test] #[should_panic] fn panic_u32_u8_1() { - let out: u8 = (0xFF_u32 + 1_u32).try_into().unwrap(); + let _out: u8 = (0xFF_u32 + 1_u32).try_into().unwrap(); } #[test] #[should_panic] fn panic_u32_u8_2() { let max_u32: u32 = 0xFFFFFFFF; - let out: u8 = max_u32.try_into().unwrap(); + let _out: u8 = max_u32.try_into().unwrap(); } #[test] #[should_panic] fn panic_u64_u8_1() { - let out: u8 = (0xFF_u64 + 1_u64).try_into().unwrap(); + let _out: u8 = (0xFF_u64 + 1_u64).try_into().unwrap(); } #[test] #[should_panic] fn panic_u64_u8_2() { let max_u64: u64 = 0xFFFFFFFFFFFFFFFF; - let out: u8 = max_u64.try_into().unwrap(); + let _out: u8 = max_u64.try_into().unwrap(); } #[test] #[should_panic] fn panic_u128_u8_1() { - let out: u8 = (0xFF_u128 + 1_u128).try_into().unwrap(); + let _out: u8 = (0xFF_u128 + 1_u128).try_into().unwrap(); } #[test] #[should_panic] fn panic_u128_u8_2() { let max_u128: u128 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; - let out: u8 = max_u128.try_into().unwrap(); + let _out: u8 = max_u128.try_into().unwrap(); } #[test] #[should_panic] fn panic_u32_u16_1() { - let out: u16 = (0xFFFF_u32 + 1_u32).try_into().unwrap(); + let _out: u16 = (0xFFFF_u32 + 1_u32).try_into().unwrap(); } #[test] #[should_panic] fn panic_u32_u16_2() { let max_u32: u32 = 0xFFFFFFFF; - let out: u16 = max_u32.try_into().unwrap(); + let _out: u16 = max_u32.try_into().unwrap(); } #[test] #[should_panic] fn panic_u64_u16_1() { - let out: u16 = (0xFFFF_u64 + 1_u64).try_into().unwrap(); + let _out: u16 = (0xFFFF_u64 + 1_u64).try_into().unwrap(); } #[test] #[should_panic] fn panic_u64_u16_2() { let max_u64: u64 = 0xFFFFFFFFFFFFFFFF; - let out: u16 = max_u64.try_into().unwrap(); + let _out: u16 = max_u64.try_into().unwrap(); } #[test] #[should_panic] fn panic_u128_u16_1() { - let out: u16 = (0xFFFF_u128 + 1_u128).try_into().unwrap(); + let _out: u16 = (0xFFFF_u128 + 1_u128).try_into().unwrap(); } #[test] #[should_panic] fn panic_u128_u16_2() { let max_u128: u128 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; - let out: u16 = max_u128.try_into().unwrap(); + let _out: u16 = max_u128.try_into().unwrap(); } #[test] #[should_panic] fn panic_u64_u32_1() { - let out: u32 = (0xFFFFFFFF_u64 + 1_u64).try_into().unwrap(); + let _out: u32 = (0xFFFFFFFF_u64 + 1_u64).try_into().unwrap(); } #[test] #[should_panic] fn panic_u64_u32_2() { let max_u64: u64 = 0xFFFFFFFFFFFFFFFF; - let out: u32 = max_u64.try_into().unwrap(); + let _out: u32 = max_u64.try_into().unwrap(); } #[test] #[should_panic] fn panic_u128_u32_1() { - let out: u32 = (0xFFFFFFFF_u128 + 1_u128).try_into().unwrap(); + let _out: u32 = (0xFFFFFFFF_u128 + 1_u128).try_into().unwrap(); } #[test] #[should_panic] fn panic_u128_u32_2() { let max_u128: u128 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; - let out: u32 = max_u128.try_into().unwrap(); + let _out: u32 = max_u128.try_into().unwrap(); } #[test] #[should_panic] fn panic_u128_u64_1() { - let out: u64 = (0xFFFFFFFFFFFFFFFF_u128 + 1_u128).try_into().unwrap(); + let _out: u64 = (0xFFFFFFFFFFFFFFFF_u128 + 1_u128).try_into().unwrap(); } #[test] #[should_panic] fn panic_u128_u64_2() { let max_u128: u128 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; - let out: u64 = max_u128.try_into().unwrap(); + let _out: u64 = max_u128.try_into().unwrap(); } #[test] @@ -1672,3 +1846,94 @@ fn test_signed_int_diff() { assert_eq(@integer::i128_diff(4, 3).unwrap(), @1, 'i128: 4 - 3 == 1'); assert_eq(@integer::i128_diff(3, 5).unwrap_err(), @~(2 - 1), 'i128: 3 - 5 == -2'); } + +mod special_casts { + extern type BoundedInt; + extern fn downcast(index: T) -> Option implicits(RangeCheck) nopanic; + extern fn upcast(index: T) -> S nopanic; + + impl DropBoundedInt120_180 of Drop>; + const U128_UPPER: felt252 = 0x100000000000000000000000000000000; + type BoundedIntU128Upper = + BoundedInt<0x100000000000000000000000000000000, 0x100000000000000000000000000000000>; + const U128_MAX: felt252 = 0xffffffffffffffffffffffffffffffff; + type BoundedIntU128Max = + BoundedInt<0xffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffff>; + + /// Is `value` the equivalent value of `expected` in `T` type. + fn is_some_of(value: Option, expected: felt252) -> bool { + match value { + Option::Some(v) => upcast(v) == expected, + Option::None => false, + } + } + + /// Is `value` the equivalent value (as `felt252`) of `expected` in `T` type. + fn felt252_downcast_valid(value: felt252) -> bool { + is_some_of(downcast::(value), value) + } + + /// Is `value` the equivalent value (as `felt252`) of `expected` in `T` type. + fn downcast_invalid(value: T) -> bool { + match downcast::(value) { + Option::Some(v) => { + // Just as a drop for `v`. + upcast::<_, felt252>(v); + false + }, + Option::None => true, + } + } + + #[test] + fn test_felt252_downcasts() { + assert!(downcast_invalid::>(1)); + assert!(felt252_downcast_valid::>(0)); + assert!(downcast_invalid::>(-1)); + assert!(downcast_invalid::>(-2)); + assert!(felt252_downcast_valid::>(-1)); + assert!(downcast_invalid::>(0)); + assert!(downcast_invalid::>(119)); + assert!(felt252_downcast_valid::>(120)); + assert!(felt252_downcast_valid::>(180)); + assert!(downcast_invalid::>(181)); + assert!(downcast_invalid::(U128_MAX - 1)); + assert!(felt252_downcast_valid::(U128_MAX)); + assert!(downcast_invalid::(U128_MAX + 1)); + assert!(downcast_invalid::(U128_UPPER - 1)); + assert!(felt252_downcast_valid::(U128_UPPER)); + assert!(downcast_invalid::(U128_UPPER + 1)); + } + + // Full prime range, but where the max element is 0. + type OneMinusPToZero = + BoundedInt<-0x800000000000011000000000000000000000000000000000000000000000000, 0>; + + type OneMinusPOnly = + BoundedInt< + -0x800000000000011000000000000000000000000000000000000000000000000, + -0x800000000000011000000000000000000000000000000000000000000000000 + >; + + #[test] + fn test_bounded_int_casts() { + let minus_1 = downcast::>(-1).unwrap(); + assert!(downcast::(upcast(minus_1)).is_none()); + let zero = downcast::>(0).unwrap(); + assert!(downcast::(upcast(zero)) == Option::Some(0)); + let one_minus_p = downcast::(1).unwrap(); + assert!(downcast::(upcast(one_minus_p)).is_none()); + let v119 = downcast::>(119).unwrap(); + assert!(downcast::, BoundedInt<120, 180>>(upcast(v119)).is_none()); + let v120 = downcast::>(120).unwrap(); + assert!( + is_some_of(downcast::, BoundedInt<120, 180>>(upcast(v120)), 120) + ); + let v180 = downcast::>(180).unwrap(); + assert!( + is_some_of(downcast::, BoundedInt<120, 180>>(upcast(v180)), 180) + ); + let v181 = downcast::>(181).unwrap(); + assert!(downcast::, BoundedInt<120, 180>>(upcast(v181)).is_none()); + } +} diff --git a/corelib/src/test/keccak_test.cairo b/corelib/src/test/keccak_test.cairo index ad4a36811..6c9c6c04b 100644 --- a/corelib/src/test/keccak_test.cairo +++ b/corelib/src/test/keccak_test.cairo @@ -1,8 +1,7 @@ use starknet::SyscallResultTrait; -use test::test_utils::{assert_eq, assert_ne}; +use core::test::test_utils::{assert_eq, assert_ne}; #[test] -#[available_gas(10000000)] fn test_keccak_syscall() { let input = array![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]; assert_eq( @@ -13,7 +12,6 @@ fn test_keccak_syscall() { } #[test] -#[available_gas(10000000)] fn test_keccak_hash() { let res = keccak::keccak_u256s_le_inputs(array![1].span()); assert_eq(@res.low, @0x587f7cc3722e9654ea3963d5fe8c0748, 'Wrong hash low 1'); @@ -34,7 +32,6 @@ fn test_keccak_hash() { // Same input as in `test_keccak_hash` but as a u64 array. #[test] -#[available_gas(10000000)] fn test_keccak_u64() { let mut input = array![ 0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 @@ -47,7 +44,6 @@ fn test_keccak_u64() { } #[test] -#[available_gas(10000000)] fn test_keccak_u64_full_block() { let mut input = array![ 0x0000000000000001, @@ -76,7 +72,6 @@ fn test_keccak_u64_full_block() { } #[test] -#[available_gas(10000000)] fn test_keccak_u64_full_block_minus_byte() { let mut input = array![ 0x0000000000000001, @@ -113,7 +108,6 @@ fn test_keccak_u64_full_block_minus_byte() { } #[test] -#[available_gas(10000000)] fn test_keccak_u64_full_block_minus_word() { let mut input = array![ 0x0000000000000001, @@ -141,7 +135,6 @@ fn test_keccak_u64_full_block_minus_word() { } #[test] -#[available_gas(10000000)] fn test_keccak_u64_full_block_minus_word_minus_byte() { let mut input = array![ 0x0000000000000001, @@ -177,7 +170,6 @@ fn test_keccak_u64_full_block_minus_word_minus_byte() { } #[test] -#[available_gas(10000000)] fn test_keccak_u64_full_block_minus_3_words_minus_4_bytes() { let mut input = array![ 0x0000000000000001, diff --git a/corelib/src/test/math_test.cairo b/corelib/src/test/math_test.cairo index ef3342878..bfe492a21 100644 --- a/corelib/src/test/math_test.cairo +++ b/corelib/src/test/math_test.cairo @@ -1,43 +1,42 @@ +use core::option::OptionTrait; +use core::math; + +/// Helper for making a non-zero value. +fn nz>>(n: N) -> NonZero { + n.try_into().unwrap() +} + #[test] -#[available_gas(10000000)] fn test_egcd() { - let (g, s, t, sub_direction) = math::egcd(68_u8.try_into().unwrap(), 16_u8.try_into().unwrap()); + let (g, s, t, sub_direction) = math::egcd(nz(68_u8), nz(16_u8)); assert(g == 4, 'g != 4'); assert(s == 1, 's != 1'); assert(t == 4, 't != 4'); assert(sub_direction, 'sub_direction is wrong'); assert(1 * 68 - 4 * 16 == 4, 'Sanity check failed'); - let (g, s, t, sub_direction) = math::egcd( - 240_u256.try_into().unwrap(), 46_u256.try_into().unwrap() - ); + let (g, s, t, sub_direction) = math::egcd(nz(240_u256), nz(46_u256)); assert(g == 2, 'g != 2'); assert(s == 9, 's != 9'); assert(t == 47, 't != 47'); assert(!sub_direction, 'sub_direction is wrong'); assert(47 * 46 - 9 * 240 == 2, 'Sanity check failed'); - let (g, s, t, sub_direction) = math::egcd( - 50_u128.try_into().unwrap(), 17_u128.try_into().unwrap() - ); + let (g, s, t, sub_direction) = math::egcd(nz(50_u128), nz(17_u128)); assert(g == 1, 'g != 1'); assert(s == 1, 's != 1'); assert(t == 3, 't != 3'); assert(!sub_direction, 'sub_direction is wrong'); assert(3 * 17 - 1 * 50 == 1, 'Sanity check failed'); - let (g, s, t, sub_direction) = math::egcd( - 5_u128.try_into().unwrap(), 15_u128.try_into().unwrap() - ); + let (g, s, t, sub_direction) = math::egcd(nz(5_u128), nz(15_u128)); assert(g == 5, 'g != 5'); assert(s == 1, 's != 1'); assert(t == 0, 't != 0'); assert(sub_direction, 'sub_direction is wrong'); assert(1 * 5 - 0 * 15 == 5, 'Sanity check failed'); - let (g, s, t, sub_direction) = math::egcd( - 1_u128.try_into().unwrap(), 1_u128.try_into().unwrap() - ); + let (g, s, t, sub_direction) = math::egcd(nz(1_u128), nz(1_u128)); assert(g == 1, 'g != 1'); assert(s == 0, 's != 0'); assert(t == 1, 't != 1'); @@ -46,50 +45,82 @@ fn test_egcd() { } #[test] -#[available_gas(10000000)] fn test_inv_mod() { - let inv = math::inv_mod(5_u256.try_into().unwrap(), 24_u256.try_into().unwrap()).unwrap(); - assert(inv == 5, 'inv != 5'); - - let inv = math::inv_mod(29_u128.try_into().unwrap(), 24_u128.try_into().unwrap()).unwrap(); - assert(inv == 5, 'inv != 5'); - - let inv = math::inv_mod(1_u16.try_into().unwrap(), 24_u16.try_into().unwrap()).unwrap(); - assert(inv == 1, 'inv != 1'); - - let inv = math::inv_mod(1_u32.try_into().unwrap(), 5_u32.try_into().unwrap()).unwrap(); - assert(inv == 1, 'inv != 1'); - - let inv = math::inv_mod(8_usize.try_into().unwrap(), 24_usize.try_into().unwrap()); - assert(inv.is_none(), 'inv should be None'); - - let inv = math::inv_mod(1_usize.try_into().unwrap(), 1_usize.try_into().unwrap()).unwrap(); - assert(inv == 0, 'inv != 0'); - - let inv = math::inv_mod(7_usize.try_into().unwrap(), 1_usize.try_into().unwrap()).unwrap(); - assert(inv == 0, 'inv != 0'); + assert(math::inv_mod(nz(5), nz(24)) == Option::Some(5_u256), 'inv_mov(5, 24) != 5'); + assert(math::inv_mod(nz(29), nz(24)) == Option::Some(5_u128), 'inv_mov(29, 24) != 5'); + assert(math::inv_mod(nz(1), nz(24)) == Option::Some(1_u16), 'inv_mov(1, 24) != 1'); + assert(math::inv_mod(nz(1), nz(5)) == Option::Some(1_u32), 'inv_mov(1, 5) != 1'); + assert(math::inv_mod(nz(8_usize), nz(24_usize)).is_none(), 'inv_mov(8, 24) != None'); + assert(math::inv_mod(nz(1), nz(1)) == Option::Some(0_usize), 'inv_mov(1, 1) != 0'); + assert(math::inv_mod(nz(7), nz(1)) == Option::Some(0_usize), 'inv_mov(7, 1) != 0'); } #[test] -#[available_gas(10000000)] fn test_u256_div_mod_n() { - let q = math::u256_div_mod_n(6_u256, 2_u256.try_into().unwrap(), 7_u256.try_into().unwrap()) - .unwrap(); - assert(q == 3, '6 / 2 != 3 (7)'); - - let q = math::u256_div_mod_n(5_u256, 1_u256.try_into().unwrap(), 7_u256.try_into().unwrap()) - .unwrap(); - assert(q == 5, '5 / 1 != 5 (7)'); - - let q = math::u256_div_mod_n(1_u256, 1_u256.try_into().unwrap(), 7_u256.try_into().unwrap()) - .unwrap(); - assert(q == 1, '1 / 1 != 1 (7)'); - - let q = math::u256_div_mod_n(7_u256, 2_u256.try_into().unwrap(), 13_u256.try_into().unwrap()) - .unwrap(); - assert(q == 10, '7 / 2 != 10 (13)'); + assert(math::u256_div_mod_n(6, 2, nz(7)) == Option::Some(3), '6 / 2 != 3 (7)'); + assert(math::u256_div_mod_n(5, 1, nz(7)) == Option::Some(5), '5 / 1 != 5 (7)'); + assert(math::u256_div_mod_n(1, 1, nz(7)) == Option::Some(1), '1 / 1 != 1 (7)'); + assert(math::u256_div_mod_n(7, 2, nz(13)) == Option::Some(10), '7 / 2 != 10 (13)'); + assert(math::u256_div_mod_n(0, 3, nz(13)) == Option::Some(0), '0 / 3 != 0 (13)'); + assert(math::u256_div_mod_n(4, 3, nz(6)).is_none(), '4 / 3 == None (6)'); + assert(math::u256_div_mod_n(5, 4, nz(6)).is_none(), '5 / 4 == None (6)'); + assert(math::u256_div_mod_n(2, 8, nz(4)).is_none(), '2 / 8 == None (4)'); + assert( + math::u256_div_mod_n( + 0xfa855081cc80656250605b2ecd7958ba4f0aa6799053da0d68bf76f2484decc6, + 0xe8e94a59a951af1b4c8cbd45fb8d01c1dd946de2533e3ad18845f9dbb6d12f4f, + nz(0xa3db605888ac3cd19e70c5b52220ad693566b996ef078e907578fec7758dabc9) + ) == Option::Some(0x8e70aea916ee4b782a0da9c18083ed9d867148a703615a2a88d0e7fddd4c900d), + 'Random large values 1' + ); + assert( + math::u256_div_mod_n( + 0x759426f1c0ba213b6378196b5091f5fa48f49f1d0cecfb00a7d59a51be35f609, + 0x57ff2c2e0900fce82331e396a71787a837783cca8145538eb32cb4b52104a3be, + nz(0xcb514e4d4672d8f1d952c0312afb5baae86121aa5817030d8439ce759295a029) + ) == Option::Some(0x7c9d22b40f98075c0bfd674d546bc77d775dcf021d30b88afb099834dffa951b), + 'Random large values 2' + ); +} - let q = math::u256_div_mod_n(0_u256, 3_u256.try_into().unwrap(), 13_u256.try_into().unwrap()) - .unwrap(); - assert(q == 0, '0 / 3 != 0 (13)'); +#[test] +fn test_u256_inv_mod() { + assert(math::u256_inv_mod(5, nz(24)).unwrap().into() == 5_u256, 'inv_mov(5, 24) != 5'); + assert(math::u256_inv_mod(29, nz(24)).unwrap().into() == 5_u256, 'inv_mov(29, 24) != 5'); + assert(math::u256_inv_mod(1, nz(24)).unwrap().into() == 1_u256, 'inv_mov(1, 24) != 1'); + assert(math::u256_inv_mod(1, nz(5)).unwrap().into() == 1_u256, 'inv_mov(1, 5) != 1'); + assert(math::u256_inv_mod(8, nz(24)).is_none(), 'inv_mov(8, 24) != None'); + assert(math::u256_inv_mod(1, nz(1)).is_none(), 'inv_mov(1, 1) != None'); + assert(math::u256_inv_mod(7, nz(1)).is_none(), 'inv_mov(7, 1) != None'); + assert(math::u256_inv_mod(0, nz(1)).is_none(), 'inv_mov(0, 1) != None'); + assert(math::u256_inv_mod(0, nz(7)).is_none(), 'inv_mov(0, 7) != None'); + assert(math::u256_inv_mod(3, nz(6)).is_none(), 'inv_mod(3, 6) != None'); + assert(math::u256_inv_mod(4, nz(6)).is_none(), 'inv_mod(4, 6) != None'); + assert(math::u256_inv_mod(8, nz(4)).is_none(), 'inv_mod(8, 4) != None'); + assert( + math::u256_inv_mod( + 0xea9195982bd472e30e5146ad7cb0acd954cbc75032a298ac73234b6b05e28cc1, + nz(0x4075f980fab77a3fde536dbaae600f5ea1540e01837dcec64c1f379613aa4d18) + ) + .is_none(), + 'Random 1' + ); + assert( + math::u256_inv_mod( + 0x85ef555d7a0aa34019c138defc40a1d3683dc1caa505bff286dd8069a28a2e4c, + nz(0xd71e5a5f4a4d1af45e703f9e13d1305ce149313037956247ad5edfe3e81d6353) + ) + .is_none(), + 'Random 2' + ); + let large_gcd = 0x63f7a7326f84cfca7738923db2b6d6c1b1b; + assert( + math::u256_inv_mod( + large_gcd * 0x51e28b744cc00edfb6bbbe6a9, nz(large_gcd * 0xc09497df4aa02be7fd25f10d3) + ) + .is_none(), + 'gcd ~ 2**140' + ); + let very_large_gcd = 0x74c5ef92be07ee4ad43ae8ca337390e4a5dfdbf4f1a5f09cdf412ab7ce343503; + assert(math::u256_inv_mod(very_large_gcd, nz(very_large_gcd)).is_none(), 'gcd ~ 2**256'); } diff --git a/corelib/src/test/nullable_test.cairo b/corelib/src/test/nullable_test.cairo new file mode 100644 index 000000000..22c0fbcb9 --- /dev/null +++ b/corelib/src/test/nullable_test.cairo @@ -0,0 +1,31 @@ +use core::test::test_utils::{assert_eq, assert_ne}; +use core::nullable::null; + +#[test] +fn test_nullable_felt252s() { + let x = 10; + let nullable_x = NullableTrait::new(x); + assert(!nullable_x.is_null(), 'nullable_x.is_null() true'); + assert_eq(@nullable_x.deref(), @x, '*&x != x'); + let y = 11; + let nullable_y = NullableTrait::new(y); + assert(!nullable_y.is_null(), 'nullable_y.is_null() true'); + assert_eq(@nullable_y.deref(), @y, '*&y != y'); + let null: Nullable = null(); + assert(null.is_null(), 'null.is_null() false'); +} + +// Testing `u256` as a test for objects of size larger than 1. +#[test] +fn test_nullable_u256() { + let x: u256 = 10; + let nullable_x = NullableTrait::new(x); + assert(!nullable_x.is_null(), 'nullable_x.is_null() true'); + assert_eq(@nullable_x.deref(), @x, '*&x != x'); + let y: u256 = 11; + let nullable_y = NullableTrait::new(y); + assert(!nullable_y.is_null(), 'nullable_y.is_null() true'); + assert_eq(@nullable_y.deref(), @y, '*&y != y'); + let null: Nullable = null(); + assert(null.is_null(), 'null.is_null() false'); +} diff --git a/corelib/src/test/num_test.cairo b/corelib/src/test/num_test.cairo new file mode 100644 index 000000000..bdd435791 --- /dev/null +++ b/corelib/src/test/num_test.cairo @@ -0,0 +1,17 @@ +use core::num::traits::BitSize; + +#[test] +fn test_bit_size() { + assert!(BitSize::::bits() == 8); + assert!(BitSize::::bits() == 16); + assert!(BitSize::::bits() == 32); + assert!(BitSize::::bits() == 64); + assert!(BitSize::::bits() == 128); + assert!(BitSize::::bits() == 256); + assert!(BitSize::::bits() == 8); + assert!(BitSize::::bits() == 16); + assert!(BitSize::::bits() == 32); + assert!(BitSize::::bits() == 64); + assert!(BitSize::::bits() == 128); + assert!(BitSize::::bits() == 248); +} diff --git a/corelib/src/test/panics_test.cairo b/corelib/src/test/panics_test.cairo new file mode 100644 index 000000000..5115fd35b --- /dev/null +++ b/corelib/src/test/panics_test.cairo @@ -0,0 +1,146 @@ +use core::byte_array::BYTE_ARRAY_MAGIC; +use core::{panics, panic_with_felt252}; + +#[test] +#[should_panic(expected: 'short_string')] +fn test_panic_with_short_string() { + panic_with_felt252('short_string'); +} + +#[test] +#[should_panic(expected: 1)] +fn test_panic_with_felt252() { + panic_with_felt252(1); +} + +#[test] +#[should_panic(expected: "")] +fn test_panic_with_byte_array_empty() { + let ba: ByteArray = Default::default(); + panics::panic_with_byte_array(@ba); +} + +#[test] +#[should_panic(expected: "error")] +fn test_panic_with_byte_array_short() { + let ba: ByteArray = "error"; + panics::panic_with_byte_array(@ba); +} + +#[test] +#[should_panic(expected: "long error with more than 31 characters")] +fn test_panic_with_byte_array_long() { + let ba: ByteArray = "long error with more than 31 characters"; + panics::panic_with_byte_array(@ba); +} + +#[test] +#[should_panic(expected: "long err\0r with more than 31 characters")] +fn test_panic_with_byte_array_null_in_full_word() { + let mut ba: ByteArray = "long err"; + ba.append_byte(0); + let ba2: ByteArray = "r with more than 31 characters"; + ba.append(@ba2); + panics::panic_with_byte_array(@ba); +} + +#[test] +#[should_panic(expected: "long error with more than 31 character\0s")] +fn test_panic_with_byte_array_null_in_pending() { + let mut ba: ByteArray = "long error with more than 31 character"; + ba.append_byte(0); + let ba2: ByteArray = "s"; + ba.append(@ba2); + panics::panic_with_byte_array(@ba); +} + +#[test] +#[should_panic(expected: "\0error")] +fn test_panic_with_byte_array_null_in_beginning() { + let mut ba: ByteArray = ""; + ba.append_byte(0); + let ba2: ByteArray = "error"; + ba.append(@ba2); + panics::panic_with_byte_array(@ba); +} + +#[test] +#[should_panic(expected: ("error", 11, "hello", 5, 'short_string'))] +fn test_panic_with_stacked_errors() { + let mut error = array![]; + let ba: ByteArray = "error"; + error.append(BYTE_ARRAY_MAGIC); + ba.serialize(ref error); + + error.append(11); + + let ba: ByteArray = "hello"; + error.append(BYTE_ARRAY_MAGIC); + ba.serialize(ref error); + + error.append(5); + error.append('short_string'); + + panic(error); +} + +#[test] +#[should_panic( + expected: ( + 0x46a6158a16a947e5916b2a2ca68501a45e93d7110e81aa2d6438b1c57c879a3, // BYTE_ARRAY_MAGIC + 1, + 0x161616161616161616161616161616161616161616161616161616161616161, + 0, + 0 + ) +)] +fn test_panic_with_byte_array_invalid_full_word() { + // This is a serialized ByteArray, but the full word is an invalid short string (> 2^248). + let mut error = array![ + BYTE_ARRAY_MAGIC, + 1, // A single full word. + 0x161616161616161616161616161616161616161616161616161616161616161, // The invalid full word. + 0, + 0 // pending byte is empty. + ]; + panic(error); +} + +#[test] +#[should_panic( + expected: ( + 0x46a6158a16a947e5916b2a2ca68501a45e93d7110e81aa2d6438b1c57c879a3, // BYTE_ARRAY_MAGIC + 0, + 'aa', + 1 + ) +)] +fn test_panic_with_byte_array_invalid_pending_word() { + // This is a serialized ByteArray, but the pending word length < the actual data in the pending + // word. + let mut error = array![ + BYTE_ARRAY_MAGIC, + 0, // No full words. + 'aa', + 1 // pending word length. Smaller than the actual data in the pending word. + ]; + panic(error); +} + +#[test] +#[should_panic(expected: "")] +fn test_panic_macro_empty() { + panic!() +} + +#[test] +#[should_panic(expected: "basic")] +fn test_panic_macro_basic_string() { + panic!("basic") +} + +#[test] +#[should_panic(expected: "some_format(1)")] +fn test_panic_macro_with_input() { + panic!("some_format({})", 1) +} diff --git a/corelib/src/test/plugins_test.cairo b/corelib/src/test/plugins_test.cairo index 343cc4e47..95ccf8f8c 100644 --- a/corelib/src/test/plugins_test.cairo +++ b/corelib/src/test/plugins_test.cairo @@ -1,20 +1,20 @@ -use test::test_utils::{assert_eq, assert_ne}; +use core::test::test_utils::assert_eq; -#[derive(Copy, Drop, Serde, PartialEq)] +#[derive(Copy, Debug, Drop, Serde, PartialEq)] enum EnumForSerde { A, B: u32, C: u64, } -#[derive(Drop, Default, PartialEq)] +#[derive(Drop, Debug, Default, PartialEq)] struct StructForDefault { a: felt252, b: u256, c: bool } -#[derive(Drop, Default, PartialEq)] +#[derive(Drop, Debug, Default, PartialEq)] enum EnumForDefault { A: felt252, B: u256, @@ -64,14 +64,83 @@ fn test_derive_serde_enum() { #[test] fn test_derive_default_struct() { - let actual: StructForDefault = Default::default(); - let expected = StructForDefault { a: 0, b: 0, c: bool::False }; - assert_eq(@actual, @expected, 'unexpected default value'); + assert_eq!(Default::default(), StructForDefault { a: 0, b: 0, c: false }); } #[test] fn test_derive_default_enum() { - let actual: EnumForDefault = Default::default(); - let expected = EnumForDefault::C(StructForDefault { a: 0, b: 0, c: bool::False }); - assert_eq(@actual, @expected, 'unexpected default value'); + assert_eq!(Default::default(), EnumForDefault::C(StructForDefault { a: 0, b: 0, c: false })); } + +#[derive(Copy, Debug, Drop, Serde, PartialEq)] +enum LongEnum5 { + A, + B, + C, + D, + E +} +#[derive(Copy, Debug, Drop, Serde, PartialEq)] +enum longEnum10 { + A, + B, + C, + D, + E, + F, + G, + H, + I, + J +} +#[derive(Copy, Debug, Drop, Serde, PartialEq)] +enum longEnum15 { + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O +} + + +#[test] +fn test_long_enum5_deserialize() { + let x = LongEnum5::E; + let mut output = Default::default(); + x.serialize(ref output); + let mut serialized = output.span(); + assert_eq( + @Serde::::deserialize(ref serialized).expect('failed to read'), @x, 'expected E' + ); +} +#[test] +fn test_long_enum10_deserialize() { + let x = longEnum10::J; + let mut output = Default::default(); + x.serialize(ref output); + let mut serialized = output.span(); + assert_eq( + @Serde::::deserialize(ref serialized).expect('failed to read'), @x, 'expected J' + ); +} +#[test] +fn test_long_enum15_deserialize() { + let x = longEnum15::O; + let mut output = Default::default(); + x.serialize(ref output); + let mut serialized = output.span(); + assert_eq( + @Serde::::deserialize(ref serialized).expect('failed to read'), @x, 'expected O' + ); +} + diff --git a/corelib/src/test/print_test.cairo b/corelib/src/test/print_test.cairo new file mode 100644 index 000000000..161d10a8e --- /dev/null +++ b/corelib/src/test/print_test.cairo @@ -0,0 +1,131 @@ +use core::byte_array::BYTE_ARRAY_MAGIC; +use core::debug::{PrintTrait, print_byte_array_as_string}; + +#[ignore] +#[test] +fn test_prints() { + // Valid short string. + 'hello'.print(); + + // felt252 + 1.print(); + + // Valid string with < 31 characters (no full words). + let x: ByteArray = "short, but string"; + print_byte_array_as_string(@x); + + // Valid string with > 31 characters (with a full word). + let x: ByteArray = "This is a long string with more than 31 characters."; + print_byte_array_as_string(@x); + + // Valid string as an array. + let x = array![ + BYTE_ARRAY_MAGIC, + 1, // A single full word. + 'This is a long string with more', + ' than 31 characters.', + 20 // pending word length. Bigger than the actual data in the pending word. + ]; + x.print(); + + // Only magic. + let x = array![BYTE_ARRAY_MAGIC]; + x.print(); + + // num_full_words > usize. + let x = array![BYTE_ARRAY_MAGIC, 0x100000000]; + x.print(); + + // Not enough data after num_full_words. + let x = array![BYTE_ARRAY_MAGIC, 0]; + x.print(); + + // Not enough full words. + let x = array![BYTE_ARRAY_MAGIC, 1, 0, 0]; + x.print(); + + // Too much data in full word. + let x = array![ + BYTE_ARRAY_MAGIC, + 1, // A single full word. + 0x161616161616161616161616161616161616161616161616161616161616161, // The invalid full word. + 0, + 0 // pending byte is empty. + ]; + x.print(); + + // num_pending_bytes > usize. + let x = array![BYTE_ARRAY_MAGIC, 0, 0, 0x100000000]; + x.print(); + + // "Not enough" data in pending_word (nulls in the beginning). + let x = array![ + BYTE_ARRAY_MAGIC, + 0, // No full words. + 'a', + 2 // pending word length. Bigger than the actual data in the pending word. + ]; + x.print(); + + // Too much data in pending_word. + let x = array![ + BYTE_ARRAY_MAGIC, + 0, // No full words. + 'aa', + 1 // pending word length. Smaller than the actual data in the pending word. + ]; + x.print(); + + // Valid string with Null. + let mut x: ByteArray = "Hello"; + x.append_byte(0); // '\0' + let suffix: ByteArray = "world"; + x.append(@suffix); + print_byte_array_as_string(@x); + + // Valid string with a non printable character. + let mut x: ByteArray = "Hello"; + x.append_byte(0x11); // Non printable character. + let suffix: ByteArray = "world"; + x.append(@suffix); + print_byte_array_as_string(@x); + + // Valid string with a newline. + let mut x: ByteArray = "Hello"; + x.append_byte(0xA); // '\n' + let suffix: ByteArray = "world"; + x.append(@suffix); + print_byte_array_as_string(@x); + + // Multiple values: (felt, string, short_string, felt) + let x = array![0x9999, BYTE_ARRAY_MAGIC, 0, 'hello', 5, 'world', 0x8888]; + x.print(); +} + +#[ignore] +#[test] +fn test_print_macro() { + // With a ByteArray. + let ba: ByteArray = "hello"; + print!("{}", ba); + + // With a felt252. + print!("{}", 97_felt252); + + // With an integer. + print!("{}", 97_usize); +} + +#[ignore] +#[test] +fn test_println_macro() { + // With a ByteArray. + let ba: ByteArray = "hello"; + println!("{}", ba); + + // With a felt252. + println!("{}", 97_felt252); + + // With an integer. + println!("{}", 97_usize); +} diff --git a/corelib/src/test/result_test.cairo b/corelib/src/test/result_test.cairo new file mode 100644 index 000000000..4d4fa83bb --- /dev/null +++ b/corelib/src/test/result_test.cairo @@ -0,0 +1,125 @@ +use core::result::{Result, ResultTraitImpl}; + +#[test] +fn test_result_ok_expect() { + let result: Result = Result::Ok(42); + assert(result.expect('') == 42, 'result_ok_expect'); +} + +#[test] +#[should_panic(expected: ('err msg',))] +fn test_result_err_expect() { + let result: Result = Result::Err('no'); + result.expect('err msg'); +} + +#[test] +fn test_result_ok_unwrap() { + let result: Result = Result::Ok(42); + assert(result.unwrap() == 42, 'result_ok_unwrap'); +} + +#[test] +#[should_panic(expected: ('Result::unwrap failed.',))] +fn test_result_err_unwrap() { + let result: Result = Result::Err('no'); + result.unwrap(); +} + +#[test] +fn test_result_ok_unwrap_or() { + let result: Result = Result::Ok(42); + assert(result.unwrap_or(0) == 42, 'result_ok_unwrap_or'); +} + +#[test] +fn test_result_err_unwrap_or() { + let result: Result = Result::Err('no'); + assert(result.unwrap_or(0) == 0, 'result_err_unwrap_or'); +} + +#[test] +fn test_result_ok_unwrap_or_default() { + let result: Result = Result::Ok(42); + assert(result.unwrap_or_default() == 42, 'result_ok_unwrap_or_default'); +} + +#[test] +fn test_result_err_unwrap_or_default() { + let result: Result = Result::Err('no'); + assert(result.unwrap_or_default() == 0, 'result_err_unwrap_or_default'); +} + +#[test] +#[should_panic(expected: ('err msg',))] +fn test_result_ok_expect_err() { + let result: Result = Result::Ok(42); + result.expect_err('err msg'); +} + +#[test] +fn test_result_err_expect_err() { + let result: Result = Result::Err('no'); + assert(result.expect_err('') == 'no', 'result_err_expect_err'); +} + +#[test] +#[should_panic(expected: ('Result::unwrap_err failed.',))] +fn test_result_ok_unwrap_err() { + let result: Result = Result::Ok(42); + result.unwrap_err(); +} + +#[test] +fn test_result_err_unwrap_err() { + let result: Result = Result::Err('no'); + assert(result.unwrap_err() == 'no', 'result_err_unwrap_err'); +} + +#[test] +fn test_result_ok_is_ok() { + let result: Result = Result::Ok(42); + assert(result.is_ok(), 'result_ok_is_ok'); +} + +#[test] +fn test_result_err_is_ok() { + let result: Result = Result::Err('no'); + assert(!result.is_ok(), 'result_err_is_ok'); +} + +#[test] +fn test_result_ok_is_err() { + let result: Result = Result::Ok(42); + assert(!result.is_err(), 'result_ok_is_err'); +} + +#[test] +fn test_result_err_is_err() { + let result: Result = Result::Err('no'); + assert(result.is_err(), 'result_err_is_err'); +} + +#[test] +fn test_result_ok_into_is_err() { + let result: Result = Result::Ok(42); + assert(!result.into_is_err(), 'result_ok_into_is_err'); +} + +#[test] +fn test_result_err_into_is_err() { + let result: Result = Result::Err('no'); + assert(result.into_is_err(), 'result_err_into_is_err'); +} + +#[test] +fn test_result_ok_into_is_ok() { + let result: Result = Result::Ok(42); + assert(result.into_is_ok(), 'result_ok_into_is_ok'); +} + +#[test] +fn test_result_err_into_is_ok() { + let result: Result = Result::Err('no'); + assert(!result.into_is_ok(), 'result_err_into_is_ok'); +} diff --git a/corelib/src/test/secp256k1_test.cairo b/corelib/src/test/secp256k1_test.cairo index 784fb5dec..2fb253be8 100644 --- a/corelib/src/test/secp256k1_test.cairo +++ b/corelib/src/test/secp256k1_test.cairo @@ -8,7 +8,6 @@ use starknet::secp256k1::{Secp256k1Point, Secp256k1PointImpl}; use starknet::eth_signature::verify_eth_signature; #[test] -#[available_gas(100000000)] fn test_secp256k1_recover_public_key() { let y_parity = true; let (msg_hash, signature, expected_public_key_x, expected_public_key_y, _) = @@ -64,10 +63,9 @@ fn get_message_and_signature(y_parity: bool) -> (u256, Signature, u256, u256, Et } #[test] -#[available_gas(100000000)] fn test_verify_eth_signature() { let y_parity = true; - let (msg_hash, signature, expected_public_key_x, expected_public_key_y, eth_address) = + let (msg_hash, signature, _expected_public_key_x, _expected_public_key_y, eth_address) = get_message_and_signature( :y_parity ); @@ -76,10 +74,9 @@ fn test_verify_eth_signature() { #[test] #[should_panic(expected: ('Invalid signature',))] -#[available_gas(100000000)] fn test_verify_eth_signature_wrong_eth_address() { let y_parity = true; - let (msg_hash, signature, expected_public_key_x, expected_public_key_y, eth_address) = + let (msg_hash, signature, _expected_public_key_x, _expected_public_key_y, eth_address) = get_message_and_signature( :y_parity ); @@ -89,10 +86,9 @@ fn test_verify_eth_signature_wrong_eth_address() { #[test] #[should_panic(expected: ('Signature out of range',))] -#[available_gas(100000000)] fn test_verify_eth_signature_overflowing_signature_r() { let y_parity = true; - let (msg_hash, mut signature, expected_public_key_x, expected_public_key_y, eth_address) = + let (msg_hash, mut signature, _expected_public_key_x, _expected_public_key_y, eth_address) = get_message_and_signature( :y_parity ); @@ -102,10 +98,9 @@ fn test_verify_eth_signature_overflowing_signature_r() { #[test] #[should_panic(expected: ('Signature out of range',))] -#[available_gas(100000000)] fn test_verify_eth_signature_overflowing_signature_s() { let y_parity = true; - let (msg_hash, mut signature, expected_public_key_x, expected_public_key_y, eth_address) = + let (msg_hash, mut signature, _expected_public_key_x, _expected_public_key_y, eth_address) = get_message_and_signature( :y_parity ); diff --git a/corelib/src/test/secp256r1_test.cairo b/corelib/src/test/secp256r1_test.cairo index ba91ba2aa..325e93d83 100644 --- a/corelib/src/test/secp256r1_test.cairo +++ b/corelib/src/test/secp256r1_test.cairo @@ -1,10 +1,9 @@ use starknet::{secp256r1::Secp256r1Impl, SyscallResultTrait}; use starknet::secp256_trait::{recover_public_key, Secp256PointTrait, Signature, is_valid_signature}; use starknet::secp256r1::{Secp256r1Point, Secp256r1PointImpl}; -use test::test_utils::assert_eq; +use core::test::test_utils::assert_eq; #[test] -#[available_gas(100000000)] fn test_secp256r1_recover_public_key() { let (msg_hash, signature, expected_public_key_x, expected_public_key_y, _) = get_message_and_signature(); @@ -78,17 +77,16 @@ fn test_verify_signature_overflowing_signature_s() { #[test] -#[available_gas(100_000_000)] fn test_recover_public_key_y_even() { let x: u256 = 0x502a43ce77c6f5c736a82f847fa95f8c2d483fe223b12b91047d83258a958b0f; - let y: u256 = 0xdb0a2e6710c71ba80afeb3abdf69d306ce729c7704f4ddf2eaaf0b76209fe1b0; + let _y: u256 = 0xdb0a2e6710c71ba80afeb3abdf69d306ce729c7704f4ddf2eaaf0b76209fe1b0; let r: u256 = 0x7380df4a623c5c2259a5e5f5b225d7265a9e24b3a13c101d1afddcf29e3cf8b2; let s: u256 = 0x0d131afacdd17a4ea1b544bb3ade677ff8accbe7830e15b9c225e6031155946a; let y_parity = false; let message_hash: u256 = 0x28c7fff9aef4847a82cd64280434712a5b49205831b60eea6e70614077e672eb; let recovered = recover_public_key::(message_hash, Signature { r, s, y_parity }) .unwrap(); - let (recovered_x, recovered_y) = recovered.get_coordinates().unwrap_syscall(); + let (recovered_x, _recovered_y) = recovered.get_coordinates().unwrap_syscall(); assert_eq(@recovered_x, @x, 'Signature is not valid'); } diff --git a/corelib/src/test/test_utils.cairo b/corelib/src/test/test_utils.cairo index 908ac246c..cd808a1e4 100644 --- a/corelib/src/test/test_utils.cairo +++ b/corelib/src/test/test_utils.cairo @@ -1,29 +1,29 @@ #[inline] -fn assert_eq>(a: @T, b: @T, err_code: felt252) { +pub fn assert_eq>(a: @T, b: @T, err_code: felt252) { assert(a == b, err_code); } #[inline] -fn assert_ne>(a: @T, b: @T, err_code: felt252) { +pub fn assert_ne>(a: @T, b: @T, err_code: felt252) { assert(a != b, err_code); } #[inline] -fn assert_le>(a: T, b: T, err_code: felt252) { +pub fn assert_le>(a: T, b: T, err_code: felt252) { assert(a <= b, err_code); } #[inline] -fn assert_lt>(a: T, b: T, err_code: felt252) { +pub fn assert_lt>(a: T, b: T, err_code: felt252) { assert(a < b, err_code); } #[inline] -fn assert_ge>(a: T, b: T, err_code: felt252) { +pub fn assert_ge>(a: T, b: T, err_code: felt252) { assert(a >= b, err_code); } #[inline] -fn assert_gt>(a: T, b: T, err_code: felt252) { +pub fn assert_gt>(a: T, b: T, err_code: felt252) { assert(a > b, err_code); } diff --git a/corelib/src/test/testing_test.cairo b/corelib/src/test/testing_test.cairo index 7d80eb6d5..6e5e56444 100644 --- a/corelib/src/test/testing_test.cairo +++ b/corelib/src/test/testing_test.cairo @@ -1,14 +1,14 @@ -use test::test_utils::{assert_eq, assert_ne, assert_gt}; +use core::test::test_utils::assert_gt; #[test] #[should_panic(expected: ('panic_with_felt252()',))] fn test_panic_with_felt252() { // No semicolon here: Missing implementation for core::traits::Drop:: - panic_with_felt252('panic_with_felt252()') + core::panic_with_felt252('panic_with_felt252()') } #[test] -#[should_panic(expected: ('assert(false)',))] +#[should_panic(expected: 'assert(false)')] fn test_assert_false() { assert(false, 'assert(false)'); } @@ -19,12 +19,64 @@ fn test_assert_true() { } #[test] +#[should_panic(expected: "assert(false)")] +fn test_assert_macro_false() { + assert!(false, "assert(false)"); +} + +#[test] +fn test_assert_macro_true() { + assert!(true, "assert(true)"); +} + +#[test] +fn test_assert_ne_with_description() { + assert_ne!(1, 2, "Description"); +} + +#[test] +fn test_assert_ne_no_description() { + assert_ne!(1, 2); +} + +#[test] +#[should_panic(expected: "assertion failed: `false`.")] +fn test_assert_macro_no_input() { + assert!(false); +} + +#[test] +#[should_panic(expected: "assertion `1 == 2` failed: Description +1: 1 +2: 2")] +fn test_assert_eq_with_description() { + assert_eq!(1, 2, "Description"); +} + +#[test] +#[should_panic(expected: "assertion `1 == 2` failed: 1 != 2 +1: 1 +2: 2")] +fn test_assert_eq_with_formatted_description() { + assert_eq!(1, 2, "{} != {}", 1, 2); +} + +#[test] +#[should_panic(expected: "assertion `1 == 2` failed. +1: 1 +2: 2")] +fn test_assert_eq_no_description() { + assert_eq!(1, 2); +} + +#[test] +#[available_gas(static)] fn test_get_available_gas_no_gas_supply() { - assert_eq(@testing::get_available_gas(), @0, 'expected no_gas_supply') + assert_eq!(core::testing::get_available_gas(), 0) } #[test] #[available_gas(10000)] fn test_get_available_gas_with_gas_supply() { - assert_gt(testing::get_available_gas(), 5000, 'high amount of gas used') + assert_gt(core::testing::get_available_gas(), 5000, 'high amount of gas used') } diff --git a/corelib/src/test/to_byte_array_test.cairo b/corelib/src/test/to_byte_array_test.cairo index 32fd14724..8d6f8149b 100644 --- a/corelib/src/test/to_byte_array_test.cairo +++ b/corelib/src/test/to_byte_array_test.cairo @@ -1,8 +1,7 @@ -use test::test_utils::assert_eq; -use to_byte_array::{FormatAsByteArray, AppendFormattedToByteArray}; +use core::test::test_utils::assert_eq; +use core::to_byte_array::{FormatAsByteArray, AppendFormattedToByteArray}; #[test] -#[available_gas(10000000)] fn test_to_string_hex() { let hex_base: NonZero = 16_u8.try_into().unwrap(); @@ -38,7 +37,6 @@ fn test_to_string_hex() { assert_eq(@serialized, @expected_string, 'Bad felt252 hex representation'); } #[test] -#[available_gas(10000000)] fn test_to_string_dec() { let dec_base: NonZero = 10_u8.try_into().unwrap(); @@ -75,7 +73,6 @@ fn test_to_string_dec() { } #[test] -#[available_gas(10000000)] fn test_to_string_oct() { let oct_base: NonZero = 8_u8.try_into().unwrap(); @@ -112,7 +109,6 @@ fn test_to_string_oct() { } #[test] -#[available_gas(10000000)] fn test_to_string_bin() { let bin_base: NonZero = 2_u8.try_into().unwrap(); @@ -149,7 +145,6 @@ fn test_to_string_bin() { } #[test] -#[available_gas(10000000)] fn test_to_string_base7() { let base7: NonZero = 7_u8.try_into().unwrap(); @@ -186,7 +181,6 @@ fn test_to_string_base7() { } #[test] -#[available_gas(10000000)] fn test_to_string_base36() { let base36: NonZero = 36_u8.try_into().unwrap(); @@ -223,7 +217,6 @@ fn test_to_string_base36() { } #[test] -#[available_gas(10000000)] fn test_append() { let expected = "prefix_6f"; let mut byte_array = "prefix_"; diff --git a/corelib/src/testing.cairo b/corelib/src/testing.cairo index e65f9ae02..f7dc0ffcf 100644 --- a/corelib/src/testing.cairo +++ b/corelib/src/testing.cairo @@ -1 +1 @@ -extern fn get_available_gas() -> u128 implicits(GasBuiltin) nopanic; +pub extern fn get_available_gas() -> u128 implicits(GasBuiltin) nopanic; diff --git a/corelib/src/to_byte_array.cairo b/corelib/src/to_byte_array.cairo index 305fc8121..1ee7899a1 100644 --- a/corelib/src/to_byte_array.cairo +++ b/corelib/src/to_byte_array.cairo @@ -1,22 +1,22 @@ -use byte_array::ByteArrayTrait; -use traits::{Into, TryInto}; -use option::OptionTrait; -use zeroable::Zeroable; +use core::byte_array::ByteArrayTrait; +use core::traits::{Into, TryInto}; +use core::option::OptionTrait; +use core::zeroable::Zeroable; /// Formats a type that behaves like uint to its Ascii representation and appends the formatted /// result into the given ByteArray. -trait AppendFormattedToByteArray { - fn append_formatted_to_byte_array(self: T, ref byte_array: ByteArray, base: NonZero); +pub trait AppendFormattedToByteArray { + fn append_formatted_to_byte_array(self: @T, ref byte_array: ByteArray, base: NonZero); } /// Formats the given input of a type that behaves like uint to its Ascii representation in a /// ByteArray. -trait FormatAsByteArray { - fn format_as_byte_array(self: T, base: NonZero) -> ByteArray; +pub trait FormatAsByteArray { + fn format_as_byte_array(self: @T, base: NonZero) -> ByteArray; } impl FormatAsByteArrayImpl> of FormatAsByteArray { - fn format_as_byte_array(self: T, base: NonZero) -> ByteArray { + fn format_as_byte_array(self: @T, base: NonZero) -> ByteArray { let mut byte_array = ""; self.append_formatted_to_byte_array(ref byte_array, :base); byte_array @@ -26,40 +26,40 @@ impl FormatAsByteArrayImpl> of FormatAsByteArr // === Impls of AppendFormattedToByteArray === impl U8AppendFormattedToByteArray of AppendFormattedToByteArray { - fn append_formatted_to_byte_array(self: u8, ref byte_array: ByteArray, base: NonZero) { + fn append_formatted_to_byte_array(self: @u8, ref byte_array: ByteArray, base: NonZero) { append_formatted_to_byte_array(self, ref byte_array, base); } } impl U16AppendFormattedToByteArray of AppendFormattedToByteArray { - fn append_formatted_to_byte_array(self: u16, ref byte_array: ByteArray, base: NonZero) { + fn append_formatted_to_byte_array(self: @u16, ref byte_array: ByteArray, base: NonZero) { append_formatted_to_byte_array(self, ref byte_array, base); } } impl U32AppendFormattedToByteArray of AppendFormattedToByteArray { - fn append_formatted_to_byte_array(self: u32, ref byte_array: ByteArray, base: NonZero) { + fn append_formatted_to_byte_array(self: @u32, ref byte_array: ByteArray, base: NonZero) { append_formatted_to_byte_array(self, ref byte_array, base); } } impl U64AppendFormattedToByteArray of AppendFormattedToByteArray { - fn append_formatted_to_byte_array(self: u64, ref byte_array: ByteArray, base: NonZero) { + fn append_formatted_to_byte_array(self: @u64, ref byte_array: ByteArray, base: NonZero) { append_formatted_to_byte_array(self, ref byte_array, base); } } impl U128AppendFormattedToByteArray of AppendFormattedToByteArray { - fn append_formatted_to_byte_array(self: u128, ref byte_array: ByteArray, base: NonZero) { + fn append_formatted_to_byte_array(self: @u128, ref byte_array: ByteArray, base: NonZero) { append_formatted_to_byte_array(self, ref byte_array, base); } } impl U256AppendFormattedToByteArray of AppendFormattedToByteArray { - fn append_formatted_to_byte_array(self: u256, ref byte_array: ByteArray, base: NonZero) { + fn append_formatted_to_byte_array(self: @u256, ref byte_array: ByteArray, base: NonZero) { append_formatted_to_byte_array(self, ref byte_array, base); } } impl Felt252AppendFormattedToByteArray of AppendFormattedToByteArray { fn append_formatted_to_byte_array( - self: felt252, ref byte_array: ByteArray, base: NonZero + self: @felt252, ref byte_array: ByteArray, base: NonZero ) { - let self_as_u256: u256 = self.into(); + let self_as_u256: u256 = (*self).into(); let base: felt252 = base.into(); let base: u256 = base.into(); let base: NonZero = base.try_into().unwrap(); @@ -78,7 +78,7 @@ impl Felt252AppendFormattedToByteArray of AppendFormattedToByteArray { fn append_formatted_to_byte_array< T, +Drop, +Copy, +DivRem, +TryInto, +Zeroable, >( - mut value: T, ref byte_array: ByteArray, base_nz: NonZero, + mut value: @T, ref byte_array: ByteArray, base_nz: NonZero, ) { let base: T = base_nz.into(); let base: u8 = base.try_into().unwrap(); @@ -89,21 +89,21 @@ fn append_formatted_to_byte_array< if base <= 10 { loop { - let (new_value, digit) = DivRem::div_rem(value, base_nz); - value = new_value; + let (new_value, digit) = DivRem::div_rem(*value, base_nz); + value = @new_value; let digit_as_u8: u8 = digit.try_into().unwrap(); reversed_digits.append(digit_as_u8 + '0'); - if value.is_zero() { + if (*value).is_zero() { break; }; } } else { loop { - let (new_value, digit) = DivRem::div_rem(value, base_nz); - value = new_value; + let (new_value, digit) = DivRem::div_rem(*value, base_nz); + value = @new_value; let digit_as_u8: u8 = digit.try_into().unwrap(); reversed_digits.append(get_big_base_digit_representation(:digit_as_u8)); - if value.is_zero() { + if (*value).is_zero() { break; }; }; diff --git a/corelib/src/traits.cairo b/corelib/src/traits.cairo index 18bfa28f6..0ec69bd2a 100644 --- a/corelib/src/traits.cairo +++ b/corelib/src/traits.cairo @@ -1,58 +1,58 @@ use core::panics::Panic; -trait Copy; -trait Drop; +pub trait Copy; +pub trait Drop; impl SnapshotCopy of Copy<@T>; impl SnapshotDrop of Drop<@T>; // TODO(spapini): When associated types are supported, support the general trait Add. -trait Add { +pub trait Add { fn add(lhs: T, rhs: T) -> T; } -trait AddEq { +pub trait AddEq { fn add_eq(ref self: T, other: T); } // TODO(spapini): When associated types are supported, support the general trait Sub. -trait Sub { +pub trait Sub { fn sub(lhs: T, rhs: T) -> T; } -trait SubEq { +pub trait SubEq { fn sub_eq(ref self: T, other: T); } // TODO(spapini): When associated types are supported, support the general trait Mul. -trait Mul { +pub trait Mul { fn mul(lhs: T, rhs: T) -> T; } -trait MulEq { +pub trait MulEq { fn mul_eq(ref self: T, other: T); } // TODO(spapini): When associated types are supported, support the general trait Div. -trait Div { +pub trait Div { fn div(lhs: T, rhs: T) -> T; } -trait DivEq { +pub trait DivEq { fn div_eq(ref self: T, other: T); } // TODO(spapini): When associated types are supported, support the general trait Rem. -trait Rem { +pub trait Rem { fn rem(lhs: T, rhs: T) -> T; } -trait RemEq { +pub trait RemEq { fn rem_eq(ref self: T, other: T); } // TODO(spapini): When associated types are supported, support the general trait DivRem. /// Division with remainder. -trait DivRem { +pub trait DivRem { fn div_rem(lhs: T, rhs: NonZero) -> (T, T); } -trait PartialEq { +pub trait PartialEq { fn eq(lhs: @T, rhs: @T) -> bool; fn ne(lhs: @T, rhs: @T) -> bool; } @@ -66,25 +66,25 @@ impl PartialEqSnap> of PartialEq<@T> { } // TODO(spapini): When associated types are supported, support the general trait BitAnd. -trait BitAnd { +pub trait BitAnd { fn bitand(lhs: T, rhs: T) -> T; } // TODO(spapini): When associated types are supported, support the general trait BitOr. -trait BitOr { +pub trait BitOr { fn bitor(lhs: T, rhs: T) -> T; } // TODO(spapini): When associated types are supported, support the general trait BitXor. -trait BitXor { +pub trait BitXor { fn bitxor(lhs: T, rhs: T) -> T; } -trait BitNot { +pub trait BitNot { fn bitnot(a: T) -> T; } -trait PartialOrd { +pub trait PartialOrd { fn le(lhs: T, rhs: T) -> bool; fn ge(lhs: T, rhs: T) -> bool; fn lt(lhs: T, rhs: T) -> bool; @@ -92,7 +92,8 @@ trait PartialOrd { } /// Trait for conversion between types. -trait Into { +pub trait Into { + #[must_use] fn into(self: T) -> S; } @@ -103,36 +104,36 @@ impl TIntoT of Into { } /// Trait for fallible conversion between types. -trait TryInto { +pub trait TryInto { fn try_into(self: T) -> Option; } -impl TTryIntoT of TryInto { - fn try_into(self: T) -> Option { - Option::Some(self) +impl TryIntoFromInto> of TryInto { + fn try_into(self: From) -> Option { + Option::Some(self.into()) } } -trait Neg { +pub trait Neg { fn neg(a: T) -> T; } -trait Not { +pub trait Not { fn not(a: T) -> T; } /// The following two traits are for implementing the [] operator. Only one should be implemented /// for each type. Both are not consuming of self, the first gets a snapshot of the object and /// the second gets ref. -trait IndexView { +pub trait IndexView { fn index(self: @C, index: I) -> V; } -trait Index { +pub trait Index { fn index(ref self: C, index: I) -> V; } -trait Destruct { +pub trait Destruct { fn destruct(self: T) nopanic; } // TODO(spapini): Remove this, it can lead to multiple impls and unwanted Destruct implementation. @@ -141,7 +142,7 @@ impl DestructFromDrop> of Destruct { fn destruct(self: T) nopanic {} } -trait PanicDestruct { +pub trait PanicDestruct { fn panic_destruct(self: T, ref panic: Panic) nopanic; } impl PanicDestructForDestruct> of PanicDestruct { @@ -151,7 +152,8 @@ impl PanicDestructForDestruct> of PanicDestruct { } } -trait Default { +pub trait Default { + #[must_use] fn default() -> T; } @@ -163,14 +165,15 @@ impl SnapshotDefault, +Drop> of Default<@T> { } /// Trait for types allowed as values in a Felt252Dict. -trait Felt252DictValue { +pub trait Felt252DictValue { /// Returns the default value for this type as a value in a Felt252Dict. /// Should be logically equivalent to 0. + #[must_use] fn zero_default() -> T nopanic; } // Tuple Copy impls. -impl TupleSize0Copy of Copy<()>; +pub(crate) impl TupleSize0Copy of Copy<()>; impl TupleSize1Copy> of Copy<(E0,)>; @@ -183,7 +186,7 @@ impl TupleSize4Copy< > of Copy<(E0, E1, E2, E3)>; // Tuple Drop impls. -impl TupleSize0Drop of Drop<()>; +pub(crate) impl TupleSize0Drop of Drop<()>; impl TupleSize1Drop> of Drop<(E0,)>; diff --git a/corelib/src/zeroable.cairo b/corelib/src/zeroable.cairo index 9e069377d..b22503db4 100644 --- a/corelib/src/zeroable.cairo +++ b/corelib/src/zeroable.cairo @@ -1,40 +1,49 @@ // === Zeroable === -trait Zeroable { +pub(crate) trait Zeroable { /// Returns the additive identity element of Self, 0. + #[must_use] fn zero() -> T; /// Returns whether self is equal to 0, the additive identity element. + #[must_use] fn is_zero(self: T) -> bool; /// Returns whether self is not equal to 0, the additive identity element. + #[must_use] fn is_non_zero(self: T) -> bool; } -impl Felt252Zeroable of Zeroable { - fn zero() -> felt252 { - 0 - } - #[inline(always)] - fn is_zero(self: felt252) -> bool { - self == 0 - } - #[inline(always)] - fn is_non_zero(self: felt252) -> bool { - !self.is_zero() +pub(crate) mod zero_based { + pub(crate) impl ZeroableImpl< + T, impl ZeroImpl: core::num::traits::Zero, +Drop, +Copy + > of super::Zeroable { + fn zero() -> T { + ZeroImpl::zero() + } + #[inline(always)] + fn is_zero(self: T) -> bool { + ZeroImpl::is_zero(@self) + } + #[inline(always)] + fn is_non_zero(self: T) -> bool { + ZeroImpl::is_non_zero(@self) + } } } +pub(crate) impl Felt252Zeroable = zero_based::ZeroableImpl; + // === NonZero === #[derive(Copy, Drop)] -extern type NonZero; +pub extern type NonZero; -enum IsZeroResult { +pub(crate) enum IsZeroResult { Zero, NonZero: NonZero, } extern fn unwrap_non_zero(a: NonZero) -> T nopanic; -impl NonZeroIntoImpl of Into, T> { +pub(crate) impl NonZeroIntoImpl of Into, T> { fn into(self: NonZero) -> T nopanic { unwrap_non_zero(self) } @@ -48,3 +57,28 @@ impl IsZeroResultIntoBool> of Into, bool> { } } } + +impl NonZeroPartialEq, +Copy, +Drop> of PartialEq> { + #[inline(always)] + fn eq(lhs: @NonZero, rhs: @NonZero) -> bool { + let lhs: T = (*lhs).into(); + let rhs: T = (*rhs).into(); + lhs == rhs + } + #[inline(always)] + fn ne(lhs: @NonZero, rhs: @NonZero) -> bool { + let lhs: T = (*lhs).into(); + let rhs: T = (*rhs).into(); + lhs != rhs + } +} + +impl NonZeroSerde, +Copy, +Drop, +TryInto>> of Serde> { + fn serialize(self: @NonZero, ref output: Array) { + let value: T = (*self).into(); + value.serialize(ref output); + } + fn deserialize(ref serialized: Span) -> Option> { + Serde::::deserialize(ref serialized)?.try_into() + } +} diff --git a/src/scarb.rs b/src/scarb.rs index 247b7f14c..153bc788a 100644 --- a/src/scarb.rs +++ b/src/scarb.rs @@ -79,7 +79,7 @@ pub fn scarb_run(file_path: &PathBuf) -> anyhow::Result { // Process 'exercise_crate' targets // Largely same as this - // https://github.com/software-mansion/scarb/blob/50e5d942f72a7b756c36fdc57b7899ad8b6ff7c7/extensions/scarb-cairo-run/src/main.rs#L61 + // https://github.com/software-mansion/scarb/blob/v2.5.3/extensions/scarb-cairo-run/src/main.rs#L61 for package in metadata.packages.iter() { if package.name != "exercise_crate" { continue; @@ -110,6 +110,7 @@ pub fn scarb_run(file_path: &PathBuf) -> anyhow::Result { sierra_program.program, Some(Default::default()), Default::default(), + false, )?; let result = runner @@ -165,7 +166,7 @@ pub fn scarb_test(file_path: &PathBuf) -> anyhow::Result { // Loop through packages, but only process 'exercise_crate' // Largely same as this - // https://github.com/software-mansion/scarb/blob/ff98a787cfc0d94adcc7394fa83348bc01f437d5/extensions/scarb-cairo-test/src/main.rs#L54 + // https://github.com/software-mansion/scarb/blob/v2.5.3/extensions/scarb-cairo-test/src/main.rs#L54 for package in metadata.packages.iter() { if package.name != "exercise_crate" { continue; @@ -186,6 +187,7 @@ pub fn scarb_test(file_path: &PathBuf) -> anyhow::Result { filter: "".into(), include_ignored: false, ignored: false, + run_profiler: false, }; let runner = CompiledTestRunner::new(test_compilation, config); runner.run()?;