From e59221cf84894735093152299ab8a163d85fd728 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Mon, 18 Aug 2025 16:31:28 -0300 Subject: [PATCH 01/21] Add local dependencies --- Cargo.lock | 391 ++++++++++++++++++++++++++++++++++++++++++++++++++--- Cargo.toml | 5 +- 2 files changed, 374 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 48f072a7bb..8e99e7cd1d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -126,22 +126,41 @@ version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" +[[package]] +name = "apollo_compilation_utils" +version = "0.15.0-rc.2" +dependencies = [ + "apollo_infra_utils", + "cairo-lang-sierra", + "cairo-lang-starknet-classes", + "cairo-lang-utils", + "cairo-native", + "rlimit", + "serde", + "serde_json", + "starknet-types-core", + "starknet_api", + "tempfile", + "thiserror 1.0.69", +] + [[package]] name = "apollo_compile_to_native" version = "0.15.0-rc.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce72f98e94e249a95dd1bdc95aaf326b4a14c930d8b948864f08734f6526556c" dependencies = [ + "apollo_compilation_utils", "apollo_config", + "apollo_infra_utils", + "cairo-lang-starknet-classes", + "cairo-native", "serde", + "tempfile", "validator", ] [[package]] name = "apollo_config" version = "0.15.0-rc.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c345b809e6590f25e4cf078006665125b07385c2f633d20d4fb9cab2fb49ce20" dependencies = [ "apollo_infra_utils", "clap", @@ -159,11 +178,9 @@ dependencies = [ [[package]] name = "apollo_infra_utils" version = "0.15.0-rc.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fdb3fb6422e6ebf266e6c0d3bfc64b7c1847620548a8010da5fb71213075456" dependencies = [ "assert-json-diff", - "colored", + "colored 3.0.0", "num_enum", "serde", "serde_json", @@ -177,8 +194,6 @@ dependencies = [ [[package]] name = "apollo_metrics" version = "0.15.0-rc.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a36e50d43a288fb99669cc3f97b42433bc5c077cfac4f218dfcd0cc64ba10464" dependencies = [ "indexmap 2.10.0", "metrics", @@ -187,6 +202,20 @@ dependencies = [ "regex", ] +[[package]] +name = "aquamarine" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f50776554130342de4836ba542aa85a4ddb361690d7e8df13774d7284c3d5c2" +dependencies = [ + "include_dir", + "itertools 0.10.5", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.104", +] + [[package]] name = "ark-ec" version = "0.4.2" @@ -215,7 +244,7 @@ dependencies = [ "ark-poly 0.5.0", "ark-serialize 0.5.0", "ark-std 0.5.0", - "educe", + "educe 0.6.0", "fnv", "hashbrown 0.15.4", "itertools 0.13.0", @@ -257,7 +286,7 @@ dependencies = [ "ark-std 0.5.0", "arrayvec", "digest", - "educe", + "educe 0.6.0", "itertools 0.13.0", "num-bigint", "num-traits", @@ -334,7 +363,7 @@ dependencies = [ "ark-ff 0.5.0", "ark-serialize 0.5.0", "ark-std 0.5.0", - "educe", + "educe 0.6.0", "fnv", "hashbrown 0.15.4", ] @@ -674,6 +703,26 @@ dependencies = [ "virtue", ] +[[package]] +name = "bindgen" +version = "0.71.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3" +dependencies = [ + "bitflags 2.9.1", + "cexpr", + "clang-sys", + "itertools 0.13.0", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash 2.1.1", + "shlex", + "syn 2.0.104", +] + [[package]] name = "bit-set" version = "0.8.0" @@ -737,10 +786,9 @@ dependencies = [ [[package]] name = "blockifier" version = "0.15.0-rc.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbaf04063930d0b2a0cbcb1760a2d1a58abdea5ee0ce78ca261d79f9bfc3430a" dependencies = [ "anyhow", + "apollo_compilation_utils", "apollo_compile_to_native", "apollo_config", "apollo_infra_utils", @@ -754,6 +802,7 @@ dependencies = [ "cairo-lang-casm", "cairo-lang-runner", "cairo-lang-starknet-classes", + "cairo-native", "cairo-vm", "dashmap", "derive_more 0.99.20", @@ -785,8 +834,6 @@ dependencies = [ [[package]] name = "blockifier_test_utils" version = "0.15.0-rc.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5812279370f6be789f435ae91dcfdd22f4b5405f2ec2895475a6d65f7e5cbc65" dependencies = [ "apollo_infra_utils", "cairo-lang-starknet-classes", @@ -1068,7 +1115,7 @@ dependencies = [ "cairo-lang-syntax", "cairo-lang-syntax-codegen", "cairo-lang-utils", - "colored", + "colored 3.0.0", "itertools 0.14.0", "num-bigint", "num-traits", @@ -1434,7 +1481,7 @@ checksum = "d325a9afabf56b9d20de7799fa370f83a673fc0a9ff62e0abcabf62cb1efbff9" dependencies = [ "cairo-lang-formatter", "cairo-lang-utils", - "colored", + "colored 3.0.0", "log", "pretty_assertions", ] @@ -1456,6 +1503,60 @@ dependencies = [ "smol_str", ] +[[package]] +name = "cairo-native" +version = "0.6.0" +dependencies = [ + "anyhow", + "aquamarine", + "ark-ec 0.5.0", + "ark-ff 0.5.0", + "ark-secp256k1 0.5.0", + "ark-secp256r1 0.5.0", + "bumpalo", + "cairo-lang-compiler", + "cairo-lang-defs", + "cairo-lang-filesystem", + "cairo-lang-runner", + "cairo-lang-semantic", + "cairo-lang-sierra", + "cairo-lang-sierra-ap-change", + "cairo-lang-sierra-gas", + "cairo-lang-sierra-generator", + "cairo-lang-sierra-to-casm", + "cairo-lang-starknet", + "cairo-lang-starknet-classes", + "cairo-lang-test-plugin", + "cairo-lang-utils", + "cc", + "clap", + "colored 2.2.0", + "educe 0.5.11", + "itertools 0.14.0", + "keccak", + "lazy_static 1.5.0", + "libc", + "libloading", + "llvm-sys", + "melior", + "mlir-sys", + "num-bigint", + "num-integer", + "num-traits", + "rand 0.9.2", + "serde", + "serde_json", + "sha2", + "starknet-curve 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "starknet-types-core", + "stats_alloc", + "tempfile", + "thiserror 2.0.12", + "tracing", + "tracing-subscriber", + "utf8_iter", +] + [[package]] name = "cairo-serde-macros" version = "1.0.0" @@ -1506,6 +1607,15 @@ dependencies = [ "serde", ] +[[package]] +name = "caseless" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6fd507454086c8edfd769ca6ada439193cdb209c7681712ef6275cccbfe5d8" +dependencies = [ + "unicode-normalization", +] + [[package]] name = "cc" version = "1.2.31" @@ -1515,6 +1625,15 @@ dependencies = [ "shlex", ] +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + [[package]] name = "cfg-if" version = "1.0.1" @@ -1597,6 +1716,17 @@ dependencies = [ "inout", ] +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + [[package]] name = "clap" version = "4.5.42" @@ -1663,6 +1793,16 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" +[[package]] +name = "colored" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" +dependencies = [ + "lazy_static 1.5.0", + "windows-sys 0.59.0", +] + [[package]] name = "colored" version = "3.0.0" @@ -1672,6 +1812,20 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "comrak" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39bff2cbb80102771ca62bd2375bc6f6611dc1493373440b23aa08a155538708" +dependencies = [ + "caseless", + "entities", + "memchr", + "slug", + "typed-arena", + "unicode_categories", +] + [[package]] name = "config" version = "0.14.1" @@ -1816,6 +1970,15 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "convert_case" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb402b8d4c85569410425650ce3eddc7d698ed96d39a73f941b08fb63082f1e7" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "convert_case" version = "0.8.0" @@ -2151,6 +2314,12 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "deunicode" +version = "1.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abd57806937c9cc163efc8ea3910e00a62e2aeb0b8119f1793a978088f8f6b04" + [[package]] name = "dialoguer" version = "0.11.0" @@ -2343,6 +2512,18 @@ dependencies = [ "spki", ] +[[package]] +name = "educe" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4bd92664bf78c4d3dba9b7cdafce6fa15b13ed3ed16175218196942e99168a8" +dependencies = [ + "enum-ordinalize", + "proc-macro2", + "quote", + "syn 2.0.104", +] + [[package]] name = "educe" version = "0.6.0" @@ -2412,6 +2593,12 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" +[[package]] +name = "entities" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5320ae4c3782150d900b79807611a59a99fc9a1d61d686faafc24b93fc8d7ca" + [[package]] name = "enum-ordinalize" version = "4.3.0" @@ -2631,6 +2818,7 @@ dependencies = [ "cairo-annotations", "cairo-lang-sierra", "cairo-lang-starknet-classes", + "cairo-native", "cairo-vm", "camino", "cheatnet", @@ -2687,6 +2875,7 @@ dependencies = [ "cairo-lang-starknet-classes", "cairo-lang-test-plugin", "cairo-lang-utils", + "cairo-native", "cairo-vm", "camino", "cheatnet", @@ -3716,6 +3905,16 @@ version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" +[[package]] +name = "libloading" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" +dependencies = [ + "cfg-if", + "windows-targets 0.53.3", +] + [[package]] name = "libm" version = "0.2.15" @@ -3750,6 +3949,20 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" +[[package]] +name = "llvm-sys" +version = "191.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "893cddf1adf0354b93411e413553dd4daf5c43195d73f1acfa1e394bdd371456" +dependencies = [ + "anyhow", + "cc", + "lazy_static 1.5.0", + "libc", + "regex-lite", + "semver", +] + [[package]] name = "lock_api" version = "0.4.13" @@ -3812,6 +4025,32 @@ dependencies = [ "rawpointer", ] +[[package]] +name = "melior" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2af6454b7bcd7edc8c2060a3726a18ceaed60e25c34d9f8de9c6b44e82eb647" +dependencies = [ + "melior-macro", + "mlir-sys", +] + +[[package]] +name = "melior-macro" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a99671327250df8e24e56d8304474a970e7a2c6bb8f6dc71382d188136fe4d1b" +dependencies = [ + "comrak", + "convert_case 0.7.1", + "proc-macro2", + "quote", + "regex", + "syn 2.0.104", + "tblgen", + "unindent", +] + [[package]] name = "memchr" version = "2.7.5" @@ -3879,6 +4118,15 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "mlir-sys" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cee4047ffefa7e9853412025a98b38a66968584543918cf084a6e4df9144b71b" +dependencies = [ + "bindgen", +] + [[package]] name = "mockall" version = "0.12.1" @@ -4573,6 +4821,16 @@ dependencies = [ "yansi", ] +[[package]] +name = "prettyplease" +version = "0.2.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff24dfcda44452b9816fff4cd4227e1bb73ff5a2f1bc1105aa92fb8565ce44d2" +dependencies = [ + "proc-macro2", + "syn 2.0.104", +] + [[package]] name = "primeorder" version = "0.13.6" @@ -4640,6 +4898,27 @@ dependencies = [ "version_check", ] +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", +] + [[package]] name = "proc-macro2" version = "1.0.95" @@ -4958,6 +5237,12 @@ dependencies = [ "regex-syntax 0.8.5", ] +[[package]] +name = "regex-lite" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" + [[package]] name = "regex-syntax" version = "0.6.29" @@ -5044,6 +5329,15 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rlimit" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7043b63bd0cd1aaa628e476b80e6d4023a3b50eb32789f2728908107bd0c793a" +dependencies = [ + "libc", +] + [[package]] name = "rlp" version = "0.5.2" @@ -5806,6 +6100,16 @@ version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" +[[package]] +name = "slug" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "882a80f72ee45de3cc9a5afeb2da0331d58df69e4e7d8eeb5d3c7784ae67e724" +dependencies = [ + "deunicode", + "wasm-bindgen", +] + [[package]] name = "smallvec" version = "1.15.1" @@ -6194,8 +6498,6 @@ dependencies = [ [[package]] name = "starknet_api" version = "0.15.0-rc.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0d5bda9bfa1cf2a0903c975b3b6918dddf3197b467d8de3a1e61c8760bcb2cb" dependencies = [ "apollo_infra_utils", "base64 0.13.1", @@ -6232,6 +6534,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "stats_alloc" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c0e04424e733e69714ca1bbb9204c1a57f09f5493439520f9f68c132ad25eec" + [[package]] name = "str-buf" version = "1.0.6" @@ -6377,6 +6685,18 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "tblgen" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c155c9310c9e11e6f642b4c8a30ae572ea0cad013d5c9e28bb264b52fa8163bb" +dependencies = [ + "bindgen", + "cc", + "paste", + "thiserror 2.0.12", +] + [[package]] name = "tempfile" version = "3.20.0" @@ -6780,6 +7100,16 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "tracing-serde" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1" +dependencies = [ + "serde", + "tracing-core", +] + [[package]] name = "tracing-subscriber" version = "0.3.19" @@ -6790,12 +7120,15 @@ dependencies = [ "nu-ansi-term 0.46.0", "once_cell", "regex", + "serde", + "serde_json", "sharded-slab", "smallvec", "thread_local", "tracing", "tracing-core", "tracing-log", + "tracing-serde", ] [[package]] @@ -6835,6 +7168,12 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +[[package]] +name = "typed-arena" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" + [[package]] name = "typeid" version = "1.0.3" @@ -6961,6 +7300,18 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "unicode_categories" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" + +[[package]] +name = "unindent" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3" + [[package]] name = "universal-sierra-compiler-api" version = "1.0.0" diff --git a/Cargo.toml b/Cargo.toml index 53f9464a37..5ebc7d9195 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,9 +29,9 @@ license = "MIT" license-file = "LICENSE" [workspace.dependencies] -blockifier = { version = "0.15.0-rc.2", features = ["testing", "tracing"]} +blockifier = { path = "../sequencer/crates/blockifier", features = ["testing", "tracing", "cairo_native"]} bigdecimal = "0.4.8" -starknet_api = "0.15.0-rc.2" +starknet_api = { path = "../sequencer/crates/starknet_api" } cairo-lang-casm = { version = "2.12.0", features = ["serde"] } cairo-lang-sierra = "2.12.0" cairo-lang-utils = "2.12.0" @@ -44,6 +44,7 @@ cairo-lang-test-plugin = "2.12.0" cairo-lang-starknet-classes = "2.12.0" cairo-lang-parser = "2.12.0" cairo-vm = "2.2.0" +cairo-native = { path = "../cairo_native", features = ["with-cheatcode"] } cairo-annotations = "0.5.0" dirs = "6.0.0" dialoguer = "0.11.0" From b685b22ba749d81c59b6e6909d1b6b47a88d5a73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Mon, 18 Aug 2025 16:31:42 -0300 Subject: [PATCH 02/21] Add cairo-native dep to forge --- crates/forge-runner/Cargo.toml | 1 + crates/forge/Cargo.toml | 1 + 2 files changed, 2 insertions(+) diff --git a/crates/forge-runner/Cargo.toml b/crates/forge-runner/Cargo.toml index 166ef94507..40e343cd27 100644 --- a/crates/forge-runner/Cargo.toml +++ b/crates/forge-runner/Cargo.toml @@ -25,6 +25,7 @@ rand.workspace = true url.workspace = true blockifier.workspace = true cairo-vm.workspace = true +cairo-native.workspace = true itertools.workspace = true indoc.workspace = true camino.workspace = true diff --git a/crates/forge/Cargo.toml b/crates/forge/Cargo.toml index d3502911cc..429eba92ce 100644 --- a/crates/forge/Cargo.toml +++ b/crates/forge/Cargo.toml @@ -43,6 +43,7 @@ scarb-metadata.workspace = true scarb-ui.workspace = true semver.workspace = true cairo-vm.workspace = true +cairo-native.workspace = true # openssl is being used, please do not remove it! openssl.workspace = true toml_edit.workspace = true From 4aebafab65c70ada735954a9cf07201f07062fe5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Mon, 18 Aug 2025 16:33:55 -0300 Subject: [PATCH 03/21] Add new run-native-test-case --- .../execution/entry_point.rs | 1 + crates/forge-runner/src/lib.rs | 6 +++++ crates/forge-runner/src/package_tests.rs | 2 ++ crates/forge-runner/src/running.rs | 24 ++++++++++++++----- .../forge-runner/src/running/with_config.rs | 5 ++++ crates/forge/src/run_tests/resolve_config.rs | 3 +++ crates/forge/src/run_tests/test_target.rs | 1 + crates/forge/src/test_filter.rs | 10 ++++++++ 8 files changed, 46 insertions(+), 6 deletions(-) diff --git a/crates/cheatnet/src/runtime_extensions/call_to_blockifier_runtime_extension/execution/entry_point.rs b/crates/cheatnet/src/runtime_extensions/call_to_blockifier_runtime_extension/execution/entry_point.rs index 72c877df2e..96deed08a7 100644 --- a/crates/cheatnet/src/runtime_extensions/call_to_blockifier_runtime_extension/execution/entry_point.rs +++ b/crates/cheatnet/src/runtime_extensions/call_to_blockifier_runtime_extension/execution/entry_point.rs @@ -172,6 +172,7 @@ pub fn execute_call_entry_point( cheatnet_state, context, ), + RunnableCompiledClass::V1Native(native_compiled_class_v1) => todo!(), }; context .tracked_resource_stack diff --git a/crates/forge-runner/src/lib.rs b/crates/forge-runner/src/lib.rs index 20109f848e..b6d8b6310c 100644 --- a/crates/forge-runner/src/lib.rs +++ b/crates/forge-runner/src/lib.rs @@ -5,6 +5,7 @@ use crate::test_case_summary::TestCaseSummary; use anyhow::Result; use build_trace_data::save_trace_data; use cairo_lang_sierra::program::{ConcreteTypeLongId, Function, TypeDeclaration}; +use cairo_native::executor::AotNativeExecutor; use camino::Utf8PathBuf; use cheatnet::runtime_extensions::forge_config_extension::config::RawFuzzerConfig; use foundry_ui::UI; @@ -106,6 +107,7 @@ pub fn maybe_generate_coverage( pub fn run_for_test_case( case: Arc, casm_program: Arc, + aot_executor: Arc, forge_config: Arc, versioned_program_path: Arc, send: Sender<()>, @@ -117,6 +119,7 @@ pub fn run_for_test_case( let res = run_test( case, casm_program, + aot_executor, forge_config, versioned_program_path, send, @@ -131,6 +134,7 @@ pub fn run_for_test_case( let res = run_with_fuzzing( case, casm_program, + aot_executor, forge_config.clone(), versioned_program_path, send, @@ -145,6 +149,7 @@ pub fn run_for_test_case( fn run_with_fuzzing( case: Arc, casm_program: Arc, + aot_executor: Arc, forge_config: Arc, versioned_program_path: Arc, send: Sender<()>, @@ -178,6 +183,7 @@ fn run_with_fuzzing( tasks.push(run_fuzz_test( case.clone(), casm_program.clone(), + aot_executor.clone(), forge_config.clone(), versioned_program_path.clone(), send.clone(), diff --git a/crates/forge-runner/src/package_tests.rs b/crates/forge-runner/src/package_tests.rs index 32a981f7e8..665df5a891 100644 --- a/crates/forge-runner/src/package_tests.rs +++ b/crates/forge-runner/src/package_tests.rs @@ -10,6 +10,7 @@ use cairo_lang_sierra::extensions::range_check::{RangeCheck96Type, RangeCheckTyp use cairo_lang_sierra::extensions::segment_arena::SegmentArenaType; use cairo_lang_sierra::ids::GenericTypeId; use cairo_lang_sierra::program::ProgramArtifact; +use cairo_native::executor::AotNativeExecutor; use cairo_vm::serde::deserialize_program::ReferenceManager; use cairo_vm::types::builtin_name::BuiltinName; use cairo_vm::types::program::Program; @@ -103,6 +104,7 @@ pub struct TestTarget { pub sierra_program: ProgramArtifact, pub sierra_program_path: Arc, pub casm_program: Arc, + pub aot_executor: Arc, pub test_cases: Vec>, } diff --git a/crates/forge-runner/src/running.rs b/crates/forge-runner/src/running.rs index fe8c7e8647..b37a58735a 100644 --- a/crates/forge-runner/src/running.rs +++ b/crates/forge-runner/src/running.rs @@ -10,6 +10,7 @@ use blockifier::execution::entry_point::EntryPointExecutionContext; use blockifier::execution::entry_point_execution::{prepare_call_arguments, run_entry_point}; use blockifier::execution::errors::EntryPointExecutionError; use blockifier::state::cached_state::CachedState; +use cairo_native::executor::AotNativeExecutor; use cairo_vm::Felt252; use cairo_vm::vm::errors::cairo_run_errors::CairoRunError; use cairo_vm::vm::errors::vm_errors::VirtualMachineError; @@ -61,7 +62,8 @@ pub use syscall_handler::syscall_handler_offset; #[must_use] pub fn run_test( case: Arc, - casm_program: Arc, + _casm_program: Arc, + aot_executor: Arc, forge_config: Arc, versioned_program_path: Arc, send: Sender<()>, @@ -74,9 +76,9 @@ pub fn run_test( if send.is_closed() { return TestCaseSummary::Interrupted {}; } - let run_result = run_test_case( + let run_result = run_native_test_case( &case, - &casm_program, + &aot_executor, &RuntimeConfig::from(&forge_config.test_runner_config), None, ); @@ -98,7 +100,8 @@ pub fn run_test( #[expect(clippy::too_many_arguments)] pub(crate) fn run_fuzz_test( case: Arc, - casm_program: Arc, + _casm_program: Arc, + aot_executor: Arc, forge_config: Arc, versioned_program_path: Arc, send: Sender<()>, @@ -114,9 +117,9 @@ pub(crate) fn run_fuzz_test( return TestCaseSummary::Interrupted {}; } - let run_result = run_test_case( + let run_result = run_native_test_case( &case, - &casm_program, + &aot_executor, &RuntimeConfig::from(&forge_config.test_runner_config), Some(rng), ); @@ -386,6 +389,15 @@ pub fn run_test_case( }) } +pub fn run_native_test_case( + case: &TestCaseWithResolvedConfig, + aot_executor: &AotNativeExecutor, + runtime_config: &RuntimeConfig, + fuzzer_rng: Option>>, +) -> Result { + todo!() +} + fn extract_test_case_summary( run_result: Result, case: &TestCaseWithResolvedConfig, diff --git a/crates/forge-runner/src/running/with_config.rs b/crates/forge-runner/src/running/with_config.rs index 9410ac778f..d95051665e 100644 --- a/crates/forge-runner/src/running/with_config.rs +++ b/crates/forge-runner/src/running/with_config.rs @@ -16,6 +16,7 @@ use cairo_lang_sierra::{ }; use cairo_lang_sierra_type_size::get_type_size_map; use cairo_lang_utils::unordered_hash_map::UnorderedHashMap; +use cairo_native::executor::AotNativeExecutor; use rayon::iter::IntoParallelRefIterator; use rayon::iter::ParallelIterator; use std::{collections::HashMap, sync::Arc}; @@ -78,12 +79,16 @@ pub fn test_target_with_config( }) .collect::>()?; + let aot_executor = || todo!(); + let aot_executor: AotNativeExecutor = aot_executor(); + Ok(TestTargetWithConfig { tests_location: test_target_raw.tests_location, test_cases, sierra_program: test_target_raw.sierra_program, sierra_program_path: test_target_raw.sierra_program_path.into(), casm_program, + aot_executor: Arc::new(aot_executor), }) } diff --git a/crates/forge/src/run_tests/resolve_config.rs b/crates/forge/src/run_tests/resolve_config.rs index 97dfe5e25b..488b6d1d53 100644 --- a/crates/forge/src/run_tests/resolve_config.rs +++ b/crates/forge/src/run_tests/resolve_config.rs @@ -49,6 +49,7 @@ pub async fn resolve_config( sierra_program_path: test_target.sierra_program_path, casm_program: test_target.casm_program, test_cases, + aot_executor: test_target.aot_executor, }) } @@ -183,6 +184,8 @@ mod tests { }, }], tests_location: TestTargetLocation::Lib, + #[allow(clippy::redundant_closure_call)] + aot_executor: (|| todo!())(), }; assert!( diff --git a/crates/forge/src/run_tests/test_target.rs b/crates/forge/src/run_tests/test_target.rs index 13973a0f81..99ba2ddc2f 100644 --- a/crates/forge/src/run_tests/test_target.rs +++ b/crates/forge/src/run_tests/test_target.rs @@ -54,6 +54,7 @@ pub async fn run_for_test_target( tasks.push(run_for_test_case( case, casm_program.clone(), + tests.aot_executor.clone(), forge_config.clone(), tests.sierra_program_path.clone(), send.clone(), diff --git a/crates/forge/src/test_filter.rs b/crates/forge/src/test_filter.rs index 361b843b1a..256c6e1860 100644 --- a/crates/forge/src/test_filter.rs +++ b/crates/forge/src/test_filter.rs @@ -251,6 +251,8 @@ mod tests { }, ], tests_location: TestTargetLocation::Lib, + #[allow(clippy::redundant_closure_call)] + aot_executor: (|| todo!())(), }; let tests_filter = TestsFilter::from_flags( @@ -486,6 +488,8 @@ mod tests { ), test_cases: vec![], tests_location: TestTargetLocation::Lib, + #[allow(clippy::redundant_closure_call)] + aot_executor: (|| todo!())(), }; let tests_filter = TestsFilter::from_flags( @@ -587,6 +591,8 @@ mod tests { }, ], tests_location: TestTargetLocation::Tests, + #[allow(clippy::redundant_closure_call)] + aot_executor: (|| todo!())(), }; let tests_filter = TestsFilter::from_flags( @@ -793,6 +799,8 @@ mod tests { }, ], tests_location: TestTargetLocation::Tests, + #[allow(clippy::redundant_closure_call)] + aot_executor: (|| todo!())(), }; let tests_filter = TestsFilter::from_flags( @@ -908,6 +916,8 @@ mod tests { }, ], tests_location: TestTargetLocation::Tests, + #[allow(clippy::redundant_closure_call)] + aot_executor: { (|| todo!())() }, }; let tests_filter = TestsFilter::from_flags( From 504c93f1c345c315f4295f18cd6632dfe5f80247 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Mon, 18 Aug 2025 18:55:05 -0300 Subject: [PATCH 04/21] Compile with Native --- Cargo.lock | 2 ++ Cargo.toml | 1 + crates/forge-runner/Cargo.toml | 2 ++ .../forge-runner/src/running/with_config.rs | 32 ++++++++++++++++--- 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8e99e7cd1d..15b23f2faf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2887,6 +2887,7 @@ dependencies = [ "futures", "indoc", "itertools 0.14.0", + "libloading", "num-traits", "rand 0.8.5", "rayon", @@ -2903,6 +2904,7 @@ dependencies = [ "starknet_api", "strum 0.27.2", "strum_macros 0.27.2", + "tempfile", "tokio", "toml_edit", "universal-sierra-compiler-api", diff --git a/Cargo.toml b/Cargo.toml index 5ebc7d9195..9da5e7af74 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,6 +45,7 @@ cairo-lang-starknet-classes = "2.12.0" cairo-lang-parser = "2.12.0" cairo-vm = "2.2.0" cairo-native = { path = "../cairo_native", features = ["with-cheatcode"] } +libloading = "0.8.6" cairo-annotations = "0.5.0" dirs = "6.0.0" dialoguer = "0.11.0" diff --git a/crates/forge-runner/Cargo.toml b/crates/forge-runner/Cargo.toml index 40e343cd27..75f1e2e713 100644 --- a/crates/forge-runner/Cargo.toml +++ b/crates/forge-runner/Cargo.toml @@ -26,6 +26,8 @@ url.workspace = true blockifier.workspace = true cairo-vm.workspace = true cairo-native.workspace = true +libloading.workspace = true +tempfile.workspace = true itertools.workspace = true indoc.workspace = true camino.workspace = true diff --git a/crates/forge-runner/src/running/with_config.rs b/crates/forge-runner/src/running/with_config.rs index d95051665e..359abdb375 100644 --- a/crates/forge-runner/src/running/with_config.rs +++ b/crates/forge-runner/src/running/with_config.rs @@ -7,7 +7,7 @@ use crate::{ }, running::config_run::run_config_pass, }; -use anyhow::{Result, anyhow}; +use anyhow::{Context, Result, anyhow}; use cairo_lang_sierra::{ extensions::core::{CoreLibfunc, CoreType}, ids::ConcreteTypeId, @@ -16,10 +16,14 @@ use cairo_lang_sierra::{ }; use cairo_lang_sierra_type_size::get_type_size_map; use cairo_lang_utils::unordered_hash_map::UnorderedHashMap; -use cairo_native::executor::AotNativeExecutor; +use cairo_native::{ + context::NativeContext, executor::AotNativeExecutor, module_to_object, object_to_shared_lib, +}; +use libloading::Library; use rayon::iter::IntoParallelRefIterator; use rayon::iter::ParallelIterator; use std::{collections::HashMap, sync::Arc}; +use tempfile::NamedTempFile; use universal_sierra_compiler_api::{SierraType, compile_sierra_at_path}; pub fn test_target_with_config( @@ -79,8 +83,28 @@ pub fn test_target_with_config( }) .collect::>()?; - let aot_executor = || todo!(); - let aot_executor: AotNativeExecutor = aot_executor(); + let aot_executor = { + let native_context = NativeContext::new(); + let mut native_module = native_context + .compile(&test_target_raw.sierra_program.program, true, None, None) + .context("failed to compile sierra program to native module")?; + let native_object = module_to_object( + native_module.module(), + cairo_native::OptLevel::Default, + None, + ) + .context("failed to compile native module to object")?; + let library_path = NamedTempFile::new()?.into_temp_path().keep()?; + object_to_shared_lib(&native_object, &library_path, None)?; + let library = unsafe { Library::new(&library_path)? }; + + AotNativeExecutor::new( + library, + ProgramRegistry::::new(&test_target_raw.sierra_program.program)?, + native_module.remove_metadata().unwrap_or_default(), + native_module.remove_metadata().unwrap_or_default(), + ) + }; Ok(TestTargetWithConfig { tests_location: test_target_raw.tests_location, From 2b894c7b711861d46cf3e2603799ee5a6129058f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Mon, 18 Aug 2025 18:58:47 -0300 Subject: [PATCH 05/21] Add sierra_function_id to test detail --- crates/forge-runner/src/package_tests.rs | 1 + crates/forge-runner/src/running/with_config.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/crates/forge-runner/src/package_tests.rs b/crates/forge-runner/src/package_tests.rs index 665df5a891..327ba58278 100644 --- a/crates/forge-runner/src/package_tests.rs +++ b/crates/forge-runner/src/package_tests.rs @@ -50,6 +50,7 @@ pub enum TestTargetLocation { #[derive(Debug, PartialEq, Clone, Default)] pub struct TestDetails { + pub sierra_function_id: u64, pub sierra_entry_point_statement_idx: usize, pub parameter_types: Vec<(GenericTypeId, i16)>, pub return_types: Vec<(GenericTypeId, i16)>, diff --git a/crates/forge-runner/src/running/with_config.rs b/crates/forge-runner/src/running/with_config.rs index 359abdb375..1987255bf7 100644 --- a/crates/forge-runner/src/running/with_config.rs +++ b/crates/forge-runner/src/running/with_config.rs @@ -133,6 +133,7 @@ fn build_test_details( }; TestDetails { + sierra_function_id: func.id.id, sierra_entry_point_statement_idx: func.entry_point.0, parameter_types: map_types(&func.signature.param_types), return_types: map_types(&func.signature.ret_types), From 7077a5bc3d77fd429966cf07bebf8f2691f1a9d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Tue, 19 Aug 2025 14:35:49 -0300 Subject: [PATCH 06/21] Comment the VM test_case execution for easy comparing --- crates/forge-runner/src/running.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/crates/forge-runner/src/running.rs b/crates/forge-runner/src/running.rs index b37a58735a..d9ee6aa012 100644 --- a/crates/forge-runner/src/running.rs +++ b/crates/forge-runner/src/running.rs @@ -63,7 +63,7 @@ pub use syscall_handler::syscall_handler_offset; pub fn run_test( case: Arc, _casm_program: Arc, - aot_executor: Arc, + _aot_executor: Arc, forge_config: Arc, versioned_program_path: Arc, send: Sender<()>, @@ -76,12 +76,19 @@ pub fn run_test( if send.is_closed() { return TestCaseSummary::Interrupted {}; } + let run_result = run_native_test_case( &case, - &aot_executor, + &_aot_executor, &RuntimeConfig::from(&forge_config.test_runner_config), None, ); + // let run_result = run_test_case( + // &case, + // &_casm_program, + // &RuntimeConfig::from(&forge_config.test_runner_config), + // None, + // ); if send.is_closed() { return TestCaseSummary::Interrupted {}; From 8160e36b093b8c2a4f671ddea03f1598f979ffb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Tue, 19 Aug 2025 14:46:08 -0300 Subject: [PATCH 07/21] Implement run_native_test_case --- crates/forge-runner/src/running.rs | 107 ++++++++++++++++++++++++++++- 1 file changed, 105 insertions(+), 2 deletions(-) diff --git a/crates/forge-runner/src/running.rs b/crates/forge-runner/src/running.rs index d9ee6aa012..2794ade08b 100644 --- a/crates/forge-runner/src/running.rs +++ b/crates/forge-runner/src/running.rs @@ -10,12 +10,16 @@ use blockifier::execution::entry_point::EntryPointExecutionContext; use blockifier::execution::entry_point_execution::{prepare_call_arguments, run_entry_point}; use blockifier::execution::errors::EntryPointExecutionError; use blockifier::state::cached_state::CachedState; +use cairo_lang_sierra::ids::FunctionId; +use cairo_native::Value; +use cairo_native::execution_result::ContractExecutionResult; use cairo_native::executor::AotNativeExecutor; +use cairo_native::starknet_stub::StubSyscallHandler; use cairo_vm::Felt252; use cairo_vm::vm::errors::cairo_run_errors::CairoRunError; use cairo_vm::vm::errors::vm_errors::VirtualMachineError; use camino::{Utf8Path, Utf8PathBuf}; -use cheatnet::constants as cheatnet_constants; +use cheatnet::constants::{self as cheatnet_constants, build_test_entry_point}; use cheatnet::forking::data::ForkData; use cheatnet::forking::state::ForkStateReader; use cheatnet::runtime_extensions::call_to_blockifier_runtime_extension::CallToBlockifierExtension; @@ -396,13 +400,112 @@ pub fn run_test_case( }) } +/// Executes the given test case with Cairo Native. pub fn run_native_test_case( case: &TestCaseWithResolvedConfig, aot_executor: &AotNativeExecutor, runtime_config: &RuntimeConfig, fuzzer_rng: Option>>, ) -> Result { - todo!() + let function_id = FunctionId::new(case.test_details.sierra_function_id); + let call = build_test_entry_point(); + + // The state reader is currently unused, as it requires support of the + // custom syscall handler. + let mut state_reader = ExtendedStateReader { + dict_state_reader: cheatnet_constants::build_testing_state(), + fork_state_reader: get_fork_state_reader( + runtime_config.cache_dir, + case.config.fork_config.as_ref(), + )?, + }; + if !case.config.disable_predeployed_contracts { + state_reader.predeploy_contracts(); + } + + // The cheatnet state is currently unused, as it requires support of a + // custom syscall handler + let block_info = state_reader.get_block_info()?; + let mut cheatnet_state = CheatnetState { + block_info, + ..Default::default() + }; + + // TODO: Implement a proper syscall handler like `run_test_case`. + // Tracking issue: https://github.com/lambdaclass/starknet-foundry/issues/3. + let mut syscall_handler = StubSyscallHandler::default(); + + // To implement fuzzing we need support of the syscall handler. + // Currently the argument is unused. + _ = fuzzer_rng; + + // Tests don't have any input arguments. Fuzzing tests actually take the + // arguments through cheatcode syscalls. + let args = vec![Value::Struct { + fields: vec![Value::Array(vec![])], + debug_name: None, + }]; + + // NOTE: We are using the AotNativeExecutor as its more generic, but in + // this context we are actually using it more like a contract executor. Consider + // unifying both executors and provide a more general API for executing Native. + let result = match aot_executor.invoke_dynamic_with_syscall_handler( + &function_id, + &args, + Some(call.initial_gas), + &mut syscall_handler, + ) { + Ok(result) => ContractExecutionResult::from_execution_result(result), + Err(err) => Err(err), + }; + + let call_trace = cheatnet_state.trace_data.current_call_stack.top(); + let encountered_errors = cheatnet_state.encountered_errors; + let fuzzer_args = cheatnet_state.fuzzer_args; + + // TODO: Compute resource usage properly. + // It should be the same as when using the Cairo VM. + let used_resources = UsedResources::default(); + let gas_used = GasVector::default(); + + let fork_data = state_reader + .fork_state_reader + .map(|fork_state_reader| ForkData::new(&fork_state_reader.compiled_contract_class_map())) + .unwrap_or_default(); + + Ok(match result { + Ok(result) => RunResult::Completed(Box::new(RunCompleted { + status: { + if !result.failure_flag { + RunStatus::Success(result.return_values) + } else { + RunStatus::Panic(result.return_values) + } + }, + call_trace, + gas_used, + used_resources, + encountered_errors, + fuzzer_args, + fork_data, + })), + Err(err) => { + // TODO: We are reusing a virtual machine error as a quick + // workaround. We should instead define a generic error type that + // supports both Cairo VM and Cairo Native errors. + let error = Box::new(CairoRunError::VirtualMachine(VirtualMachineError::Other( + err.into(), + ))); + + RunResult::Error(RunError { + error, + call_trace, + encountered_errors, + fuzzer_args, + fork_data, + }) + } + }) } fn extract_test_case_summary( From 39268202dbdcb72a180b4b3f02ced05eb7a3c1e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Tue, 19 Aug 2025 17:44:20 -0300 Subject: [PATCH 08/21] Use git dependencies --- Cargo.lock | 9 +++++++++ Cargo.toml | 6 +++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 15b23f2faf..b0621b2ac2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -129,6 +129,7 @@ checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" [[package]] name = "apollo_compilation_utils" version = "0.15.0-rc.2" +source = "git+https://github.com/lambdaclass/sequencer.git?rev=3117630b9470f70832d2a08f758aa3df2486fbe8#3117630b9470f70832d2a08f758aa3df2486fbe8" dependencies = [ "apollo_infra_utils", "cairo-lang-sierra", @@ -147,6 +148,7 @@ dependencies = [ [[package]] name = "apollo_compile_to_native" version = "0.15.0-rc.2" +source = "git+https://github.com/lambdaclass/sequencer.git?rev=3117630b9470f70832d2a08f758aa3df2486fbe8#3117630b9470f70832d2a08f758aa3df2486fbe8" dependencies = [ "apollo_compilation_utils", "apollo_config", @@ -161,6 +163,7 @@ dependencies = [ [[package]] name = "apollo_config" version = "0.15.0-rc.2" +source = "git+https://github.com/lambdaclass/sequencer.git?rev=3117630b9470f70832d2a08f758aa3df2486fbe8#3117630b9470f70832d2a08f758aa3df2486fbe8" dependencies = [ "apollo_infra_utils", "clap", @@ -178,6 +181,7 @@ dependencies = [ [[package]] name = "apollo_infra_utils" version = "0.15.0-rc.2" +source = "git+https://github.com/lambdaclass/sequencer.git?rev=3117630b9470f70832d2a08f758aa3df2486fbe8#3117630b9470f70832d2a08f758aa3df2486fbe8" dependencies = [ "assert-json-diff", "colored 3.0.0", @@ -194,6 +198,7 @@ dependencies = [ [[package]] name = "apollo_metrics" version = "0.15.0-rc.2" +source = "git+https://github.com/lambdaclass/sequencer.git?rev=3117630b9470f70832d2a08f758aa3df2486fbe8#3117630b9470f70832d2a08f758aa3df2486fbe8" dependencies = [ "indexmap 2.10.0", "metrics", @@ -786,6 +791,7 @@ dependencies = [ [[package]] name = "blockifier" version = "0.15.0-rc.2" +source = "git+https://github.com/lambdaclass/sequencer.git?rev=3117630b9470f70832d2a08f758aa3df2486fbe8#3117630b9470f70832d2a08f758aa3df2486fbe8" dependencies = [ "anyhow", "apollo_compilation_utils", @@ -834,6 +840,7 @@ dependencies = [ [[package]] name = "blockifier_test_utils" version = "0.15.0-rc.2" +source = "git+https://github.com/lambdaclass/sequencer.git?rev=3117630b9470f70832d2a08f758aa3df2486fbe8#3117630b9470f70832d2a08f758aa3df2486fbe8" dependencies = [ "apollo_infra_utils", "cairo-lang-starknet-classes", @@ -1506,6 +1513,7 @@ dependencies = [ [[package]] name = "cairo-native" version = "0.6.0" +source = "git+https://github.com/lambdaclass/cairo_native.git?rev=5bf88591687b3f3596ac592357b029cfb1ab79b2#5bf88591687b3f3596ac592357b029cfb1ab79b2" dependencies = [ "anyhow", "aquamarine", @@ -6500,6 +6508,7 @@ dependencies = [ [[package]] name = "starknet_api" version = "0.15.0-rc.2" +source = "git+https://github.com/lambdaclass/sequencer.git?rev=3117630b9470f70832d2a08f758aa3df2486fbe8#3117630b9470f70832d2a08f758aa3df2486fbe8" dependencies = [ "apollo_infra_utils", "base64 0.13.1", diff --git a/Cargo.toml b/Cargo.toml index 9da5e7af74..41014a3d1c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,9 +29,9 @@ license = "MIT" license-file = "LICENSE" [workspace.dependencies] -blockifier = { path = "../sequencer/crates/blockifier", features = ["testing", "tracing", "cairo_native"]} +blockifier = { git = "https://github.com/lambdaclass/sequencer.git", rev = "3117630b9470f70832d2a08f758aa3df2486fbe8", features = ["testing", "tracing", "cairo_native"]} bigdecimal = "0.4.8" -starknet_api = { path = "../sequencer/crates/starknet_api" } +starknet_api = { git = "https://github.com/lambdaclass/sequencer.git", rev = "3117630b9470f70832d2a08f758aa3df2486fbe8" } cairo-lang-casm = { version = "2.12.0", features = ["serde"] } cairo-lang-sierra = "2.12.0" cairo-lang-utils = "2.12.0" @@ -44,7 +44,7 @@ cairo-lang-test-plugin = "2.12.0" cairo-lang-starknet-classes = "2.12.0" cairo-lang-parser = "2.12.0" cairo-vm = "2.2.0" -cairo-native = { path = "../cairo_native", features = ["with-cheatcode"] } +cairo-native = { git = "https://github.com/lambdaclass/cairo_native.git", rev = "5bf88591687b3f3596ac592357b029cfb1ab79b2", features = ["with-cheatcode"] } libloading = "0.8.6" cairo-annotations = "0.5.0" dirs = "6.0.0" From 5812c24ad9cc3d511ca76ad7653506291e2a2f99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Tue, 19 Aug 2025 18:24:55 -0300 Subject: [PATCH 09/21] Remove todo! from tests --- Cargo.lock | 1 + .../execution/entry_point.rs | 4 +- crates/forge/Cargo.toml | 1 + crates/forge/src/run_tests/resolve_config.rs | 38 +++++++++++++- crates/forge/src/test_filter.rs | 51 +++++++++++++++---- 5 files changed, 82 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b0621b2ac2..4f700e7f15 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2843,6 +2843,7 @@ dependencies = [ "include_dir", "indoc", "itertools 0.14.0", + "libloading", "num-bigint", "openssl", "packages_validation", diff --git a/crates/cheatnet/src/runtime_extensions/call_to_blockifier_runtime_extension/execution/entry_point.rs b/crates/cheatnet/src/runtime_extensions/call_to_blockifier_runtime_extension/execution/entry_point.rs index 96deed08a7..259e0f99e4 100644 --- a/crates/cheatnet/src/runtime_extensions/call_to_blockifier_runtime_extension/execution/entry_point.rs +++ b/crates/cheatnet/src/runtime_extensions/call_to_blockifier_runtime_extension/execution/entry_point.rs @@ -172,7 +172,9 @@ pub fn execute_call_entry_point( cheatnet_state, context, ), - RunnableCompiledClass::V1Native(native_compiled_class_v1) => todo!(), + RunnableCompiledClass::V1Native(_) => { + todo!("execute inner call with Cairo Native") + } }; context .tracked_resource_stack diff --git a/crates/forge/Cargo.toml b/crates/forge/Cargo.toml index 429eba92ce..570130caf7 100644 --- a/crates/forge/Cargo.toml +++ b/crates/forge/Cargo.toml @@ -44,6 +44,7 @@ scarb-ui.workspace = true semver.workspace = true cairo-vm.workspace = true cairo-native.workspace = true +libloading.workspace = true # openssl is being used, please do not remove it! openssl.workspace = true toml_edit.workspace = true diff --git a/crates/forge/src/run_tests/resolve_config.rs b/crates/forge/src/run_tests/resolve_config.rs index 488b6d1d53..699c13975a 100644 --- a/crates/forge/src/run_tests/resolve_config.rs +++ b/crates/forge/src/run_tests/resolve_config.rs @@ -127,12 +127,19 @@ fn replace_id_with_params( #[cfg(test)] mod tests { use super::*; + use cairo_lang_sierra::extensions::core::{CoreLibfunc, CoreType}; use cairo_lang_sierra::program::ProgramArtifact; + use cairo_lang_sierra::program_registry::ProgramRegistry; use cairo_lang_sierra::{ids::GenericTypeId, program::Program}; + use cairo_native::context::NativeContext; + use cairo_native::executor::AotNativeExecutor; + use cairo_native::{module_to_object, object_to_shared_lib}; use forge_runner::package_tests::TestTargetLocation; use forge_runner::package_tests::with_config::{TestCaseConfig, TestCaseWithConfig}; use forge_runner::{expected_result::ExpectedTestResult, package_tests::TestDetails}; + use libloading::Library; use std::sync::Arc; + use tempfile::NamedTempFile; use universal_sierra_compiler_api::{SierraType, compile_sierra}; use url::Url; @@ -148,6 +155,33 @@ mod tests { } } + fn executor_for_testing() -> Arc { + let native_context = NativeContext::new(); + let mut native_module = native_context + .compile(&program_for_testing().program, true, None, None) + .unwrap(); + let native_object = module_to_object( + native_module.module(), + cairo_native::OptLevel::Default, + None, + ) + .unwrap(); + let library_path = NamedTempFile::new() + .unwrap() + .into_temp_path() + .keep() + .unwrap(); + object_to_shared_lib(&native_object, &library_path, None).unwrap(); + let library = unsafe { Library::new(&library_path).unwrap() }; + let native_executor = AotNativeExecutor::new( + library, + ProgramRegistry::::new(&program_for_testing().program).unwrap(), + native_module.remove_metadata().unwrap_or_default(), + native_module.remove_metadata().unwrap_or_default(), + ); + Arc::new(native_executor) + } + #[tokio::test] async fn to_runnable_non_existent_id() { let mocked_tests = TestTargetWithConfig { @@ -171,6 +205,7 @@ mod tests { disable_predeployed_contracts: false, }, test_details: TestDetails { + sierra_function_id: 100, sierra_entry_point_statement_idx: 100, parameter_types: vec![ (GenericTypeId("RangeCheck".into()), 1), @@ -184,8 +219,7 @@ mod tests { }, }], tests_location: TestTargetLocation::Lib, - #[allow(clippy::redundant_closure_call)] - aot_executor: (|| todo!())(), + aot_executor: executor_for_testing(), }; assert!( diff --git a/crates/forge/src/test_filter.rs b/crates/forge/src/test_filter.rs index 256c6e1860..db373b0d70 100644 --- a/crates/forge/src/test_filter.rs +++ b/crates/forge/src/test_filter.rs @@ -133,14 +133,23 @@ impl TestCaseFilter for TestsFilter { mod tests { use crate::shared_cache::FailedTestsCache; use crate::test_filter::TestsFilter; + use cairo_lang_sierra::extensions::core::CoreLibfunc; + use cairo_lang_sierra::extensions::core::CoreType; use cairo_lang_sierra::program::Program; use cairo_lang_sierra::program::ProgramArtifact; + use cairo_lang_sierra::program_registry::ProgramRegistry; + use cairo_native::context::NativeContext; + use cairo_native::executor::AotNativeExecutor; + use cairo_native::module_to_object; + use cairo_native::object_to_shared_lib; use forge_runner::expected_result::ExpectedTestResult; use forge_runner::package_tests::with_config_resolved::{ TestCaseResolvedConfig, TestCaseWithResolvedConfig, TestTargetWithResolvedConfig, }; use forge_runner::package_tests::{TestDetails, TestTargetLocation}; + use libloading::Library; use std::sync::Arc; + use tempfile::NamedTempFile; use universal_sierra_compiler_api::{SierraType, compile_sierra}; fn program_for_testing() -> ProgramArtifact { @@ -155,6 +164,33 @@ mod tests { } } + fn executor_for_testing() -> Arc { + let native_context = NativeContext::new(); + let mut native_module = native_context + .compile(&program_for_testing().program, true, None, None) + .unwrap(); + let native_object = module_to_object( + native_module.module(), + cairo_native::OptLevel::Default, + None, + ) + .unwrap(); + let library_path = NamedTempFile::new() + .unwrap() + .into_temp_path() + .keep() + .unwrap(); + object_to_shared_lib(&native_object, &library_path, None).unwrap(); + let library = unsafe { Library::new(&library_path).unwrap() }; + let native_executor = AotNativeExecutor::new( + library, + ProgramRegistry::::new(&program_for_testing().program).unwrap(), + native_module.remove_metadata().unwrap_or_default(), + native_module.remove_metadata().unwrap_or_default(), + ); + Arc::new(native_executor) + } + #[test] #[should_panic(expected = "Arguments only_ignored and include_ignored cannot be both true")] fn from_flags_only_ignored_and_include_ignored_both_true() { @@ -251,8 +287,7 @@ mod tests { }, ], tests_location: TestTargetLocation::Lib, - #[allow(clippy::redundant_closure_call)] - aot_executor: (|| todo!())(), + aot_executor: executor_for_testing(), }; let tests_filter = TestsFilter::from_flags( @@ -488,8 +523,7 @@ mod tests { ), test_cases: vec![], tests_location: TestTargetLocation::Lib, - #[allow(clippy::redundant_closure_call)] - aot_executor: (|| todo!())(), + aot_executor: executor_for_testing(), }; let tests_filter = TestsFilter::from_flags( @@ -591,8 +625,7 @@ mod tests { }, ], tests_location: TestTargetLocation::Tests, - #[allow(clippy::redundant_closure_call)] - aot_executor: (|| todo!())(), + aot_executor: executor_for_testing(), }; let tests_filter = TestsFilter::from_flags( @@ -799,8 +832,7 @@ mod tests { }, ], tests_location: TestTargetLocation::Tests, - #[allow(clippy::redundant_closure_call)] - aot_executor: (|| todo!())(), + aot_executor: executor_for_testing(), }; let tests_filter = TestsFilter::from_flags( @@ -916,8 +948,7 @@ mod tests { }, ], tests_location: TestTargetLocation::Tests, - #[allow(clippy::redundant_closure_call)] - aot_executor: { (|| todo!())() }, + aot_executor: executor_for_testing(), }; let tests_filter = TestsFilter::from_flags( From 165f31e4184686086e552414001d5b4887fa742b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Wed, 20 Aug 2025 12:07:54 -0300 Subject: [PATCH 10/21] Use from_native_module --- Cargo.lock | 3 -- Cargo.toml | 1 - crates/forge-runner/Cargo.toml | 2 -- .../forge-runner/src/running/with_config.rs | 26 +++------------- crates/forge/Cargo.toml | 1 - crates/forge/src/run_tests/resolve_config.rs | 29 +++-------------- crates/forge/src/test_filter.rs | 31 +++---------------- 7 files changed, 12 insertions(+), 81 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4f700e7f15..08c0bcae5e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2843,7 +2843,6 @@ dependencies = [ "include_dir", "indoc", "itertools 0.14.0", - "libloading", "num-bigint", "openssl", "packages_validation", @@ -2896,7 +2895,6 @@ dependencies = [ "futures", "indoc", "itertools 0.14.0", - "libloading", "num-traits", "rand 0.8.5", "rayon", @@ -2913,7 +2911,6 @@ dependencies = [ "starknet_api", "strum 0.27.2", "strum_macros 0.27.2", - "tempfile", "tokio", "toml_edit", "universal-sierra-compiler-api", diff --git a/Cargo.toml b/Cargo.toml index 41014a3d1c..74dd85055c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,7 +45,6 @@ cairo-lang-starknet-classes = "2.12.0" cairo-lang-parser = "2.12.0" cairo-vm = "2.2.0" cairo-native = { git = "https://github.com/lambdaclass/cairo_native.git", rev = "5bf88591687b3f3596ac592357b029cfb1ab79b2", features = ["with-cheatcode"] } -libloading = "0.8.6" cairo-annotations = "0.5.0" dirs = "6.0.0" dialoguer = "0.11.0" diff --git a/crates/forge-runner/Cargo.toml b/crates/forge-runner/Cargo.toml index 75f1e2e713..40e343cd27 100644 --- a/crates/forge-runner/Cargo.toml +++ b/crates/forge-runner/Cargo.toml @@ -26,8 +26,6 @@ url.workspace = true blockifier.workspace = true cairo-vm.workspace = true cairo-native.workspace = true -libloading.workspace = true -tempfile.workspace = true itertools.workspace = true indoc.workspace = true camino.workspace = true diff --git a/crates/forge-runner/src/running/with_config.rs b/crates/forge-runner/src/running/with_config.rs index 1987255bf7..f95c2e091a 100644 --- a/crates/forge-runner/src/running/with_config.rs +++ b/crates/forge-runner/src/running/with_config.rs @@ -16,14 +16,10 @@ use cairo_lang_sierra::{ }; use cairo_lang_sierra_type_size::get_type_size_map; use cairo_lang_utils::unordered_hash_map::UnorderedHashMap; -use cairo_native::{ - context::NativeContext, executor::AotNativeExecutor, module_to_object, object_to_shared_lib, -}; -use libloading::Library; +use cairo_native::{context::NativeContext, executor::AotNativeExecutor}; use rayon::iter::IntoParallelRefIterator; use rayon::iter::ParallelIterator; use std::{collections::HashMap, sync::Arc}; -use tempfile::NamedTempFile; use universal_sierra_compiler_api::{SierraType, compile_sierra_at_path}; pub fn test_target_with_config( @@ -85,25 +81,11 @@ pub fn test_target_with_config( let aot_executor = { let native_context = NativeContext::new(); - let mut native_module = native_context + let native_module = native_context .compile(&test_target_raw.sierra_program.program, true, None, None) .context("failed to compile sierra program to native module")?; - let native_object = module_to_object( - native_module.module(), - cairo_native::OptLevel::Default, - None, - ) - .context("failed to compile native module to object")?; - let library_path = NamedTempFile::new()?.into_temp_path().keep()?; - object_to_shared_lib(&native_object, &library_path, None)?; - let library = unsafe { Library::new(&library_path)? }; - - AotNativeExecutor::new( - library, - ProgramRegistry::::new(&test_target_raw.sierra_program.program)?, - native_module.remove_metadata().unwrap_or_default(), - native_module.remove_metadata().unwrap_or_default(), - ) + AotNativeExecutor::from_native_module(native_module, cairo_native::OptLevel::Default) + .context("failed to create executor")? }; Ok(TestTargetWithConfig { diff --git a/crates/forge/Cargo.toml b/crates/forge/Cargo.toml index 570130caf7..429eba92ce 100644 --- a/crates/forge/Cargo.toml +++ b/crates/forge/Cargo.toml @@ -44,7 +44,6 @@ scarb-ui.workspace = true semver.workspace = true cairo-vm.workspace = true cairo-native.workspace = true -libloading.workspace = true # openssl is being used, please do not remove it! openssl.workspace = true toml_edit.workspace = true diff --git a/crates/forge/src/run_tests/resolve_config.rs b/crates/forge/src/run_tests/resolve_config.rs index 699c13975a..8fe4b1c9a9 100644 --- a/crates/forge/src/run_tests/resolve_config.rs +++ b/crates/forge/src/run_tests/resolve_config.rs @@ -127,19 +127,14 @@ fn replace_id_with_params( #[cfg(test)] mod tests { use super::*; - use cairo_lang_sierra::extensions::core::{CoreLibfunc, CoreType}; use cairo_lang_sierra::program::ProgramArtifact; - use cairo_lang_sierra::program_registry::ProgramRegistry; use cairo_lang_sierra::{ids::GenericTypeId, program::Program}; use cairo_native::context::NativeContext; use cairo_native::executor::AotNativeExecutor; - use cairo_native::{module_to_object, object_to_shared_lib}; use forge_runner::package_tests::TestTargetLocation; use forge_runner::package_tests::with_config::{TestCaseConfig, TestCaseWithConfig}; use forge_runner::{expected_result::ExpectedTestResult, package_tests::TestDetails}; - use libloading::Library; use std::sync::Arc; - use tempfile::NamedTempFile; use universal_sierra_compiler_api::{SierraType, compile_sierra}; use url::Url; @@ -157,28 +152,12 @@ mod tests { fn executor_for_testing() -> Arc { let native_context = NativeContext::new(); - let mut native_module = native_context + let native_module = native_context .compile(&program_for_testing().program, true, None, None) .unwrap(); - let native_object = module_to_object( - native_module.module(), - cairo_native::OptLevel::Default, - None, - ) - .unwrap(); - let library_path = NamedTempFile::new() - .unwrap() - .into_temp_path() - .keep() - .unwrap(); - object_to_shared_lib(&native_object, &library_path, None).unwrap(); - let library = unsafe { Library::new(&library_path).unwrap() }; - let native_executor = AotNativeExecutor::new( - library, - ProgramRegistry::::new(&program_for_testing().program).unwrap(), - native_module.remove_metadata().unwrap_or_default(), - native_module.remove_metadata().unwrap_or_default(), - ); + let native_executor = + AotNativeExecutor::from_native_module(native_module, cairo_native::OptLevel::Default) + .unwrap(); Arc::new(native_executor) } diff --git a/crates/forge/src/test_filter.rs b/crates/forge/src/test_filter.rs index db373b0d70..2d99f9c2a0 100644 --- a/crates/forge/src/test_filter.rs +++ b/crates/forge/src/test_filter.rs @@ -133,23 +133,16 @@ impl TestCaseFilter for TestsFilter { mod tests { use crate::shared_cache::FailedTestsCache; use crate::test_filter::TestsFilter; - use cairo_lang_sierra::extensions::core::CoreLibfunc; - use cairo_lang_sierra::extensions::core::CoreType; use cairo_lang_sierra::program::Program; use cairo_lang_sierra::program::ProgramArtifact; - use cairo_lang_sierra::program_registry::ProgramRegistry; use cairo_native::context::NativeContext; use cairo_native::executor::AotNativeExecutor; - use cairo_native::module_to_object; - use cairo_native::object_to_shared_lib; use forge_runner::expected_result::ExpectedTestResult; use forge_runner::package_tests::with_config_resolved::{ TestCaseResolvedConfig, TestCaseWithResolvedConfig, TestTargetWithResolvedConfig, }; use forge_runner::package_tests::{TestDetails, TestTargetLocation}; - use libloading::Library; use std::sync::Arc; - use tempfile::NamedTempFile; use universal_sierra_compiler_api::{SierraType, compile_sierra}; fn program_for_testing() -> ProgramArtifact { @@ -166,28 +159,12 @@ mod tests { fn executor_for_testing() -> Arc { let native_context = NativeContext::new(); - let mut native_module = native_context + let native_module = native_context .compile(&program_for_testing().program, true, None, None) .unwrap(); - let native_object = module_to_object( - native_module.module(), - cairo_native::OptLevel::Default, - None, - ) - .unwrap(); - let library_path = NamedTempFile::new() - .unwrap() - .into_temp_path() - .keep() - .unwrap(); - object_to_shared_lib(&native_object, &library_path, None).unwrap(); - let library = unsafe { Library::new(&library_path).unwrap() }; - let native_executor = AotNativeExecutor::new( - library, - ProgramRegistry::::new(&program_for_testing().program).unwrap(), - native_module.remove_metadata().unwrap_or_default(), - native_module.remove_metadata().unwrap_or_default(), - ); + let native_executor = + AotNativeExecutor::from_native_module(native_module, cairo_native::OptLevel::Default) + .unwrap(); Arc::new(native_executor) } From adf332b93184689ccdefedcf73433e52eb07275a Mon Sep 17 00:00:00 2001 From: Diego Civini Date: Wed, 20 Aug 2025 16:55:11 -0300 Subject: [PATCH 11/21] Add cli argument to choose between native and vm --- crates/forge-runner/src/forge_config.rs | 1 + crates/forge-runner/src/running.rs | 27 ++++++++++++++----------- crates/forge/src/combine_configs.rs | 10 +++++++++ crates/forge/src/lib.rs | 4 +++- crates/forge/src/run_tests/package.rs | 1 + 5 files changed, 30 insertions(+), 13 deletions(-) diff --git a/crates/forge-runner/src/forge_config.rs b/crates/forge-runner/src/forge_config.rs index 50fea06d52..f1551e4ecf 100644 --- a/crates/forge-runner/src/forge_config.rs +++ b/crates/forge-runner/src/forge_config.rs @@ -27,6 +27,7 @@ pub struct TestRunnerConfig { pub environment_variables: HashMap, pub tracked_resource: ForgeTrackedResource, pub experimental_oracles: bool, + pub use_native: bool, } #[derive(Debug, PartialEq)] diff --git a/crates/forge-runner/src/running.rs b/crates/forge-runner/src/running.rs index 2794ade08b..4bd0721ca8 100644 --- a/crates/forge-runner/src/running.rs +++ b/crates/forge-runner/src/running.rs @@ -81,18 +81,21 @@ pub fn run_test( return TestCaseSummary::Interrupted {}; } - let run_result = run_native_test_case( - &case, - &_aot_executor, - &RuntimeConfig::from(&forge_config.test_runner_config), - None, - ); - // let run_result = run_test_case( - // &case, - // &_casm_program, - // &RuntimeConfig::from(&forge_config.test_runner_config), - // None, - // ); + let run_result = if forge_config.test_runner_config.use_native { + run_native_test_case( + &case, + &_aot_executor, + &RuntimeConfig::from(&forge_config.test_runner_config), + None, + ) + } else { + run_test_case( + &case, + &_casm_program, + &RuntimeConfig::from(&forge_config.test_runner_config), + None, + ) + }; if send.is_closed() { return TestCaseSummary::Interrupted {}; diff --git a/crates/forge/src/combine_configs.rs b/crates/forge/src/combine_configs.rs index 9fcfb05d22..820aa31085 100644 --- a/crates/forge/src/combine_configs.rs +++ b/crates/forge/src/combine_configs.rs @@ -29,6 +29,7 @@ pub fn combine_configs( additional_args: &[OsString], trace_args: TraceArgs, experimental_oracles: bool, + use_native: bool, ) -> ForgeConfig { let execution_data_to_save = ExecutionDataToSave::from_flags( save_trace_data || forge_config_from_scarb.save_trace_data, @@ -53,6 +54,7 @@ pub fn combine_configs( tracked_resource, environment_variables: env::vars().collect(), experimental_oracles, + use_native, }), output_config: Arc::new(OutputConfig { trace_args, @@ -84,6 +86,7 @@ mod tests { &[], TraceArgs::default(), false, + false, ); let config2 = combine_configs( false, @@ -101,6 +104,7 @@ mod tests { &[], TraceArgs::default(), false, + false, ); assert_ne!(config.test_runner_config.fuzzer_seed, 0); @@ -129,6 +133,7 @@ mod tests { &[], TraceArgs::default(), false, + false, ); assert_eq!( config, @@ -144,6 +149,7 @@ mod tests { contracts_data: ContractsData::default(), environment_variables: config.test_runner_config.environment_variables.clone(), experimental_oracles: false, + use_native: false }), output_config: Arc::new(OutputConfig { detailed_resources: false, @@ -185,6 +191,7 @@ mod tests { &[], TraceArgs::default(), false, + false, ); assert_eq!( config, @@ -200,6 +207,7 @@ mod tests { contracts_data: ContractsData::default(), environment_variables: config.test_runner_config.environment_variables.clone(), experimental_oracles: false, + use_native: false }), output_config: Arc::new(OutputConfig { detailed_resources: true, @@ -245,6 +253,7 @@ mod tests { &[], TraceArgs::default(), false, + false, ); assert_eq!( @@ -261,6 +270,7 @@ mod tests { contracts_data: ContractsData::default(), environment_variables: config.test_runner_config.environment_variables.clone(), experimental_oracles: false, + use_native: false }), output_config: Arc::new(OutputConfig { detailed_resources: true, diff --git a/crates/forge/src/lib.rs b/crates/forge/src/lib.rs index 81fb2004d2..52eefb4fb7 100644 --- a/crates/forge/src/lib.rs +++ b/crates/forge/src/lib.rs @@ -220,6 +220,9 @@ pub struct TestArgs { #[arg(long, default_value_t = false, env = "SNFORGE_EXPERIMENTAL_ORACLES")] experimental_oracles: bool, + #[arg(long, default_value_t = false)] + use_native: bool, + #[command(flatten)] scarb_args: ScarbArgs, } @@ -274,7 +277,6 @@ pub enum ExitStatus { pub fn main_execution(ui: Arc) -> Result { let cli = Cli::parse(); - match cli.subcommand { ForgeSubcommand::Init { name } => { init::init(name.as_str(), &ui)?; diff --git a/crates/forge/src/run_tests/package.rs b/crates/forge/src/run_tests/package.rs index a2677a20e0..52f0bdd20e 100644 --- a/crates/forge/src/run_tests/package.rs +++ b/crates/forge/src/run_tests/package.rs @@ -108,6 +108,7 @@ impl RunForPackageArgs { &args.additional_args, args.trace_args.clone(), args.experimental_oracles, + args.use_native, )); let test_filter = TestsFilter::from_flags( From 2fa85818e79a1df6a30f4ae947bfcdd77daa5801 Mon Sep 17 00:00:00 2001 From: Diego Civini Date: Wed, 20 Aug 2025 17:54:27 -0300 Subject: [PATCH 12/21] Add makefile and benchmark script --- Makefile | 3 +++ scripts/benchmarks.sh | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 Makefile create mode 100755 scripts/benchmarks.sh diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000..ab3d37d7e2 --- /dev/null +++ b/Makefile @@ -0,0 +1,3 @@ +bench: + cargo b --release --bin snforge + ./scripts/benchmarks.sh diff --git a/scripts/benchmarks.sh b/scripts/benchmarks.sh new file mode 100755 index 0000000000..1614d37071 --- /dev/null +++ b/scripts/benchmarks.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +PROGRAMS_DIR="scarb_programs/" + +run_bench() { + hyperfine \ + --warmup 5 \ + '../../target/release/snforge test --use-native' \ + '../../target/release/snforge test' +} + +for dir in "$PROGRAMS_DIR"/*/; do + ( + cd "$dir" + run_bench + ) +done + From c51a51bf4cfb8edb5e58dd457e5cafd9db28173b Mon Sep 17 00:00:00 2001 From: Diego Civini Date: Wed, 20 Aug 2025 18:01:09 -0300 Subject: [PATCH 13/21] Add scarb proyect with factorial tests --- Makefile | 1 - scarb_programs/hello_starknet/Scarb.toml | 52 +++++++++++++++++++ scarb_programs/hello_starknet/snfoundry.toml | 11 ++++ scarb_programs/hello_starknet/src/lib.cairo | 32 ++++++++++++ .../hello_starknet/tests/test_contract.cairo | 29 +++++++++++ scripts/benchmarks.sh | 2 +- 6 files changed, 125 insertions(+), 2 deletions(-) create mode 100644 scarb_programs/hello_starknet/Scarb.toml create mode 100644 scarb_programs/hello_starknet/snfoundry.toml create mode 100644 scarb_programs/hello_starknet/src/lib.cairo create mode 100644 scarb_programs/hello_starknet/tests/test_contract.cairo diff --git a/Makefile b/Makefile index ab3d37d7e2..b1b1e66ee4 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,2 @@ bench: - cargo b --release --bin snforge ./scripts/benchmarks.sh diff --git a/scarb_programs/hello_starknet/Scarb.toml b/scarb_programs/hello_starknet/Scarb.toml new file mode 100644 index 0000000000..542514ef46 --- /dev/null +++ b/scarb_programs/hello_starknet/Scarb.toml @@ -0,0 +1,52 @@ +[package] +name = "hello_starknet" +version = "0.1.0" +edition = "2024_07" + +# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html + +[dependencies] +starknet = "2.11.2" + +[dev-dependencies] +snforge_std_deprecated = "0.48.0" +assert_macros = "2.11.2" + +[[target.starknet-contract]] +sierra = true + +[scripts] +test = "snforge test" + +[tool.scarb] +allow-prebuilt-plugins = ["snforge_std_deprecated"] + +# Visit https://foundry-rs.github.io/starknet-foundry/appendix/scarb-toml.html for more information + +# [tool.snforge] # Define `snforge` tool section +# exit_first = true # Stop tests execution immediately upon the first failure +# fuzzer_runs = 1234 # Number of runs of the random fuzzer +# fuzzer_seed = 1111 # Seed for the random fuzzer + +# [[tool.snforge.fork]] # Used for fork testing +# name = "SOME_NAME" # Fork name +# url = "http://your.rpc.url" # Url of the RPC provider +# block_id.tag = "latest" # Block to fork from (block tag) + +# [[tool.snforge.fork]] +# name = "SOME_SECOND_NAME" +# url = "http://your.second.rpc.url" +# block_id.number = "123" # Block to fork from (block number) + +# [[tool.snforge.fork]] +# name = "SOME_THIRD_NAME" +# url = "http://your.third.rpc.url" +# block_id.hash = "0x123" # Block to fork from (block hash) + +# [profile.dev.cairo] # Configure Cairo compiler +# unstable-add-statements-code-locations-debug-info = true # Should be used if you want to use coverage +# unstable-add-statements-functions-debug-info = true # Should be used if you want to use coverage/profiler +# inlining-strategy = "avoid" # Should be used if you want to use coverage + +# [features] # Used for conditional compilation +# enable_for_tests = [] # Feature name and list of other features that should be enabled with it diff --git a/scarb_programs/hello_starknet/snfoundry.toml b/scarb_programs/hello_starknet/snfoundry.toml new file mode 100644 index 0000000000..0f29e90db6 --- /dev/null +++ b/scarb_programs/hello_starknet/snfoundry.toml @@ -0,0 +1,11 @@ +# Visit https://foundry-rs.github.io/starknet-foundry/appendix/snfoundry-toml.html +# and https://foundry-rs.github.io/starknet-foundry/projects/configuration.html for more information + +# [sncast.default] # Define a profile name +# url = "https://starknet-sepolia.public.blastapi.io/rpc/v0_8" # Url of the RPC provider +# accounts-file = "../account-file" # Path to the file with the account data +# account = "mainuser" # Account from `accounts_file` or default account file that will be used for the transactions +# keystore = "~/keystore" # Path to the keystore file +# wait-params = { timeout = 300, retry-interval = 10 } # Wait for submitted transaction parameters +# block-explorer = "StarkScan" # Block explorer service used to display links to transaction details +# show-explorer-links = true # Print links pointing to pages with transaction details in the chosen block explorer diff --git a/scarb_programs/hello_starknet/src/lib.cairo b/scarb_programs/hello_starknet/src/lib.cairo new file mode 100644 index 0000000000..9a718e324a --- /dev/null +++ b/scarb_programs/hello_starknet/src/lib.cairo @@ -0,0 +1,32 @@ +/// Interface representing `HelloContract`. +/// This interface allows modification and retrieval of the contract balance. +#[starknet::interface] +pub trait IHelloStarknet { + /// Increase contract balance. + fn increase_balance(ref self: TContractState, amount: felt252); + /// Retrieve contract balance. + fn get_balance(self: @TContractState) -> felt252; +} + +/// Simple contract for managing balance. +#[starknet::contract] +mod HelloStarknet { + use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; + + #[storage] + struct Storage { + balance: felt252, + } + + #[abi(embed_v0)] + impl HelloStarknetImpl of super::IHelloStarknet { + fn increase_balance(ref self: ContractState, amount: felt252) { + assert(amount != 0, 'Amount cannot be 0'); + self.balance.write(self.balance.read() + amount); + } + + fn get_balance(self: @ContractState) -> felt252 { + self.balance.read() + } + } +} diff --git a/scarb_programs/hello_starknet/tests/test_contract.cairo b/scarb_programs/hello_starknet/tests/test_contract.cairo new file mode 100644 index 0000000000..310c9f2ba5 --- /dev/null +++ b/scarb_programs/hello_starknet/tests/test_contract.cairo @@ -0,0 +1,29 @@ +use starknet::ContractAddress; + +use snforge_std_deprecated::{declare, ContractClassTrait, DeclareResultTrait}; + +use hello_starknet::IHelloStarknetSafeDispatcher; +use hello_starknet::IHelloStarknetSafeDispatcherTrait; +use hello_starknet::IHelloStarknetDispatcher; +use hello_starknet::IHelloStarknetDispatcherTrait; + +fn deploy_contract(name: ByteArray) -> ContractAddress { + let contract = declare(name).unwrap().contract_class(); + let (contract_address, _) = contract.deploy(@ArrayTrait::new()).unwrap(); + contract_address +} + +pub fn factorial(a: felt252) -> felt252 { + if a == 1 || a == 0 { + return 1; + } + return a * factorial(a - 1); +} +#[test] +fn test_factorial() { + assert_eq!(factorial(2), 2, "bad factorial"); + assert_eq!(factorial(3), 6, "bad factorial"); + assert_eq!(factorial(4), 24, "bad factorial"); + assert_eq!(factorial(10), 3628800, "bad factorial"); + assert_eq!(factorial(2000000), 0x4d6e41de886ac83938da3456ccf1481182687989ead34d9d35236f0864575a0, "bad factorial") +} diff --git a/scripts/benchmarks.sh b/scripts/benchmarks.sh index 1614d37071..3b394e8a6c 100755 --- a/scripts/benchmarks.sh +++ b/scripts/benchmarks.sh @@ -6,7 +6,7 @@ run_bench() { hyperfine \ --warmup 5 \ '../../target/release/snforge test --use-native' \ - '../../target/release/snforge test' + '../../target/release/snforge test --max-n-steps 100000000' } for dir in "$PROGRAMS_DIR"/*/; do From 39512e5bbd109eb7eb6f2dc12273370bc6b76ee8 Mon Sep 17 00:00:00 2001 From: Diego Civini Date: Thu, 21 Aug 2025 10:24:27 -0300 Subject: [PATCH 14/21] Use optimized factorial function --- .../hello_starknet/tests/test_contract.cairo | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/scarb_programs/hello_starknet/tests/test_contract.cairo b/scarb_programs/hello_starknet/tests/test_contract.cairo index 310c9f2ba5..f0ba22978b 100644 --- a/scarb_programs/hello_starknet/tests/test_contract.cairo +++ b/scarb_programs/hello_starknet/tests/test_contract.cairo @@ -13,12 +13,14 @@ fn deploy_contract(name: ByteArray) -> ContractAddress { contract_address } -pub fn factorial(a: felt252) -> felt252 { - if a == 1 || a == 0 { - return 1; +fn factorial(value: felt252, n: felt252) -> felt252 { + if (n == 1) { + value + } else { + factorial(value * n, n - 1) } - return a * factorial(a - 1); } + #[test] fn test_factorial() { assert_eq!(factorial(2), 2, "bad factorial"); From 400323fa193915d23538b373d6c74daa5fe741db Mon Sep 17 00:00:00 2001 From: Diego Civini Date: Thu, 21 Aug 2025 11:14:39 -0300 Subject: [PATCH 15/21] Move factorial to a program instead of a contract --- crates/forge/test_utils/src/running_tests.rs | 1 + crates/forge/tests/integration/setup_fork.rs | 2 ++ .../Scarb.toml | 6 +--- .../snfoundry.toml | 0 scarb_programs/cairo_program/src/lib.cairo | 25 +++++++++++++++ scarb_programs/hello_starknet/src/lib.cairo | 32 ------------------- .../hello_starknet/tests/test_contract.cairo | 31 ------------------ 7 files changed, 29 insertions(+), 68 deletions(-) rename scarb_programs/{hello_starknet => cairo_program}/Scarb.toml (96%) rename scarb_programs/{hello_starknet => cairo_program}/snfoundry.toml (100%) create mode 100644 scarb_programs/cairo_program/src/lib.cairo delete mode 100644 scarb_programs/hello_starknet/src/lib.cairo delete mode 100644 scarb_programs/hello_starknet/tests/test_contract.cairo diff --git a/crates/forge/test_utils/src/running_tests.rs b/crates/forge/test_utils/src/running_tests.rs index c1609ab26c..5faa132ffb 100644 --- a/crates/forge/test_utils/src/running_tests.rs +++ b/crates/forge/test_utils/src/running_tests.rs @@ -79,6 +79,7 @@ pub fn run_test_case( tracked_resource, environment_variables: test.env().clone(), experimental_oracles: false, + use_native: false, }), output_config: Arc::new(OutputConfig { detailed_resources: false, diff --git a/crates/forge/tests/integration/setup_fork.rs b/crates/forge/tests/integration/setup_fork.rs index eb7e9175e3..6ec50be48b 100644 --- a/crates/forge/tests/integration/setup_fork.rs +++ b/crates/forge/tests/integration/setup_fork.rs @@ -161,6 +161,7 @@ fn fork_aliased_decorator() { tracked_resource: ForgeTrackedResource::CairoSteps, environment_variables: test.env().clone(), experimental_oracles: false, + use_native: false, }), output_config: Arc::new(OutputConfig { detailed_resources: false, @@ -254,6 +255,7 @@ fn fork_aliased_decorator_overrding() { tracked_resource: ForgeTrackedResource::CairoSteps, environment_variables: test.env().clone(), experimental_oracles: false, + use_native: false, }), output_config: Arc::new(OutputConfig { detailed_resources: false, diff --git a/scarb_programs/hello_starknet/Scarb.toml b/scarb_programs/cairo_program/Scarb.toml similarity index 96% rename from scarb_programs/hello_starknet/Scarb.toml rename to scarb_programs/cairo_program/Scarb.toml index 542514ef46..005a131740 100644 --- a/scarb_programs/hello_starknet/Scarb.toml +++ b/scarb_programs/cairo_program/Scarb.toml @@ -1,20 +1,16 @@ [package] -name = "hello_starknet" +name = "cairo_program" version = "0.1.0" edition = "2024_07" # See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html [dependencies] -starknet = "2.11.2" [dev-dependencies] snforge_std_deprecated = "0.48.0" assert_macros = "2.11.2" -[[target.starknet-contract]] -sierra = true - [scripts] test = "snforge test" diff --git a/scarb_programs/hello_starknet/snfoundry.toml b/scarb_programs/cairo_program/snfoundry.toml similarity index 100% rename from scarb_programs/hello_starknet/snfoundry.toml rename to scarb_programs/cairo_program/snfoundry.toml diff --git a/scarb_programs/cairo_program/src/lib.cairo b/scarb_programs/cairo_program/src/lib.cairo new file mode 100644 index 0000000000..3180ccac03 --- /dev/null +++ b/scarb_programs/cairo_program/src/lib.cairo @@ -0,0 +1,25 @@ +fn main() -> felt252 { + factorial(1, 1) +} + +fn factorial(value: felt252, n: felt252) -> felt252 { + if (n == 1) { + value + } else { + factorial(value * n, n - 1) + } +} + +#[cfg(test)] +mod tests { + use super::factorial; + + #[test] + fn test_factorial() { + assert_eq!(factorial(1, 2), 2, "bad factorial"); + assert_eq!(factorial(1, 3), 6, "bad factorial"); + assert_eq!(factorial(1, 4), 24, "bad factorial"); + assert_eq!(factorial(1, 10), 3628800, "bad factorial"); + assert_eq!(factorial(1, 2000000), 0x4d6e41de886ac83938da3456ccf1481182687989ead34d9d35236f0864575a0, "bad factorial"); + } +} diff --git a/scarb_programs/hello_starknet/src/lib.cairo b/scarb_programs/hello_starknet/src/lib.cairo deleted file mode 100644 index 9a718e324a..0000000000 --- a/scarb_programs/hello_starknet/src/lib.cairo +++ /dev/null @@ -1,32 +0,0 @@ -/// Interface representing `HelloContract`. -/// This interface allows modification and retrieval of the contract balance. -#[starknet::interface] -pub trait IHelloStarknet { - /// Increase contract balance. - fn increase_balance(ref self: TContractState, amount: felt252); - /// Retrieve contract balance. - fn get_balance(self: @TContractState) -> felt252; -} - -/// Simple contract for managing balance. -#[starknet::contract] -mod HelloStarknet { - use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; - - #[storage] - struct Storage { - balance: felt252, - } - - #[abi(embed_v0)] - impl HelloStarknetImpl of super::IHelloStarknet { - fn increase_balance(ref self: ContractState, amount: felt252) { - assert(amount != 0, 'Amount cannot be 0'); - self.balance.write(self.balance.read() + amount); - } - - fn get_balance(self: @ContractState) -> felt252 { - self.balance.read() - } - } -} diff --git a/scarb_programs/hello_starknet/tests/test_contract.cairo b/scarb_programs/hello_starknet/tests/test_contract.cairo deleted file mode 100644 index f0ba22978b..0000000000 --- a/scarb_programs/hello_starknet/tests/test_contract.cairo +++ /dev/null @@ -1,31 +0,0 @@ -use starknet::ContractAddress; - -use snforge_std_deprecated::{declare, ContractClassTrait, DeclareResultTrait}; - -use hello_starknet::IHelloStarknetSafeDispatcher; -use hello_starknet::IHelloStarknetSafeDispatcherTrait; -use hello_starknet::IHelloStarknetDispatcher; -use hello_starknet::IHelloStarknetDispatcherTrait; - -fn deploy_contract(name: ByteArray) -> ContractAddress { - let contract = declare(name).unwrap().contract_class(); - let (contract_address, _) = contract.deploy(@ArrayTrait::new()).unwrap(); - contract_address -} - -fn factorial(value: felt252, n: felt252) -> felt252 { - if (n == 1) { - value - } else { - factorial(value * n, n - 1) - } -} - -#[test] -fn test_factorial() { - assert_eq!(factorial(2), 2, "bad factorial"); - assert_eq!(factorial(3), 6, "bad factorial"); - assert_eq!(factorial(4), 24, "bad factorial"); - assert_eq!(factorial(10), 3628800, "bad factorial"); - assert_eq!(factorial(2000000), 0x4d6e41de886ac83938da3456ccf1481182687989ead34d9d35236f0864575a0, "bad factorial") -} From 6dc9d2fd154f6b042c698bbc73703bfb09f4818b Mon Sep 17 00:00:00 2001 From: Diego Civini Date: Thu, 21 Aug 2025 12:31:55 -0300 Subject: [PATCH 16/21] Add dict tests --- scarb_programs/cairo_program/src/lib.cairo | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/scarb_programs/cairo_program/src/lib.cairo b/scarb_programs/cairo_program/src/lib.cairo index 3180ccac03..5ffa990d5d 100644 --- a/scarb_programs/cairo_program/src/lib.cairo +++ b/scarb_programs/cairo_program/src/lib.cairo @@ -1,3 +1,5 @@ +use core::dict::Felt252Dict; + fn main() -> felt252 { factorial(1, 1) } @@ -10,9 +12,20 @@ fn factorial(value: felt252, n: felt252) -> felt252 { } } +fn init_dict(length: u64) -> Felt252Dict { + let mut balances: Felt252Dict = Default::default(); + + for i in 0..length { + let x: felt252 = i.into(); + balances.insert(x, x); + }; + + return balances; +} + #[cfg(test)] mod tests { - use super::factorial; + use super::{factorial, init_dict}; #[test] fn test_factorial() { @@ -22,4 +35,11 @@ mod tests { assert_eq!(factorial(1, 10), 3628800, "bad factorial"); assert_eq!(factorial(1, 2000000), 0x4d6e41de886ac83938da3456ccf1481182687989ead34d9d35236f0864575a0, "bad factorial"); } + + #[test] + fn test_dict() { + let mut dict = init_dict(1000001); + let last = dict.get(1000000); + assert_eq!(last, 1000000, "invalid result"); + } } From c080be369b7f4f4f3406e4b2fc3951fa81b7de51 Mon Sep 17 00:00:00 2001 From: Diego Civini Date: Thu, 21 Aug 2025 12:32:37 -0300 Subject: [PATCH 17/21] Add fibonacci tests --- scarb_programs/cairo_program/src/lib.cairo | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/scarb_programs/cairo_program/src/lib.cairo b/scarb_programs/cairo_program/src/lib.cairo index 5ffa990d5d..4bb6fecef3 100644 --- a/scarb_programs/cairo_program/src/lib.cairo +++ b/scarb_programs/cairo_program/src/lib.cairo @@ -23,6 +23,13 @@ fn init_dict(length: u64) -> Felt252Dict { return balances; } +fn fib(a: felt252, b: felt252, n: felt252) -> felt252 { + match n { + 0 => a, + _ => fib(b, a + b, n - 1), + } +} + #[cfg(test)] mod tests { use super::{factorial, init_dict}; @@ -42,4 +49,10 @@ mod tests { let last = dict.get(1000000); assert_eq!(last, 1000000, "invalid result"); } + + #[test] + fn test_fibonacci() { + assert_eq!(fib(0, 1, 10), 55, 'invalid result'); + assert_eq!(fib(0, 1, 2000000), 0x79495858064f7881b9eff3a923642b2990b5a4342da5470eb2251df58d9acfb, 'invalid result'); + } } From 403a5ffebd27bf009450025b2b5be79e87b68c37 Mon Sep 17 00:00:00 2001 From: Diego Civini Date: Thu, 21 Aug 2025 12:37:26 -0300 Subject: [PATCH 18/21] Fix errors --- scarb_programs/cairo_program/src/lib.cairo | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scarb_programs/cairo_program/src/lib.cairo b/scarb_programs/cairo_program/src/lib.cairo index 4bb6fecef3..355e4c3021 100644 --- a/scarb_programs/cairo_program/src/lib.cairo +++ b/scarb_programs/cairo_program/src/lib.cairo @@ -32,7 +32,7 @@ fn fib(a: felt252, b: felt252, n: felt252) -> felt252 { #[cfg(test)] mod tests { - use super::{factorial, init_dict}; + use super::{factorial, init_dict, fib}; #[test] fn test_factorial() { @@ -52,7 +52,7 @@ mod tests { #[test] fn test_fibonacci() { - assert_eq!(fib(0, 1, 10), 55, 'invalid result'); - assert_eq!(fib(0, 1, 2000000), 0x79495858064f7881b9eff3a923642b2990b5a4342da5470eb2251df58d9acfb, 'invalid result'); + assert_eq!(fib(0, 1, 10), 55, "invalid result"); + assert_eq!(fib(0, 1, 2000000), 0x79495858064f7881b9eff3a923642b2990b5a4342da5470eb2251df58d9acfb, "invalid result"); } } From 982fbd02f8fc19966f390da541729fb6cdda248a Mon Sep 17 00:00:00 2001 From: Diego Civini Date: Thu, 21 Aug 2025 14:37:05 -0300 Subject: [PATCH 19/21] Add tests for linear search --- scarb_programs/cairo_program/src/lib.cairo | 49 +++++++++++++++++++--- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/scarb_programs/cairo_program/src/lib.cairo b/scarb_programs/cairo_program/src/lib.cairo index 355e4c3021..163aa6a118 100644 --- a/scarb_programs/cairo_program/src/lib.cairo +++ b/scarb_programs/cairo_program/src/lib.cairo @@ -30,17 +30,40 @@ fn fib(a: felt252, b: felt252, n: felt252) -> felt252 { } } +fn search(array: @Array, number: felt252) -> u32 { + let mut index = 0; + + while index < array.len() { + if *array[index] == number { + break; + } + + index += 1; + }; + + return index; +} + +fn init_array(length: u32) -> Array { + let mut array = ArrayTrait::new(); + for i in 0..length { + array.append(i.into()); + }; + + return array; +} + #[cfg(test)] mod tests { - use super::{factorial, init_dict, fib}; + use super::{factorial, init_dict, fib, init_array, search}; #[test] fn test_factorial() { - assert_eq!(factorial(1, 2), 2, "bad factorial"); - assert_eq!(factorial(1, 3), 6, "bad factorial"); - assert_eq!(factorial(1, 4), 24, "bad factorial"); - assert_eq!(factorial(1, 10), 3628800, "bad factorial"); - assert_eq!(factorial(1, 2000000), 0x4d6e41de886ac83938da3456ccf1481182687989ead34d9d35236f0864575a0, "bad factorial"); + assert_eq!(factorial(1, 2), 2, "invalid result"); + assert_eq!(factorial(1, 3), 6, "invalid result"); + assert_eq!(factorial(1, 4), 24, "invalid result"); + assert_eq!(factorial(1, 10), 3628800, "invalid result"); + assert_eq!(factorial(1, 2000000), 0x4d6e41de886ac83938da3456ccf1481182687989ead34d9d35236f0864575a0, "invalid result"); } #[test] @@ -55,4 +78,18 @@ mod tests { assert_eq!(fib(0, 1, 10), 55, "invalid result"); assert_eq!(fib(0, 1, 2000000), 0x79495858064f7881b9eff3a923642b2990b5a4342da5470eb2251df58d9acfb, "invalid result"); } + + #[test] + fn test_linear_search() { + let array = init_array(4001); + + let index = search(@array, 1000); + assert_eq!(index, 1000, "invalid result"); + let index = search(@array, 2000); + assert_eq!(index, 2000, "invalid result"); + let index = search(@array, 3000); + assert_eq!(index, 3000, "invalid result"); + let index = search(@array, 4000); + assert_eq!(index, 4000, "invalid result"); + } } From ed008e12fdb2b1e2008cfaadf55759b86bff52bd Mon Sep 17 00:00:00 2001 From: Diego Civini Date: Thu, 21 Aug 2025 14:43:17 -0300 Subject: [PATCH 20/21] Add tests for map iteration --- scarb_programs/cairo_program/src/lib.cairo | 30 +++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/scarb_programs/cairo_program/src/lib.cairo b/scarb_programs/cairo_program/src/lib.cairo index 163aa6a118..9c21f8322a 100644 --- a/scarb_programs/cairo_program/src/lib.cairo +++ b/scarb_programs/cairo_program/src/lib.cairo @@ -53,9 +53,17 @@ fn init_array(length: u32) -> Array { return array; } +// Logistic map implementation. +// +// The value would normally be a number between zero and one, however since floats are not +// available, zero corresponds to a felt zero and one to PRIME - 1. +fn iterate_map(r: felt252, x: felt252) -> felt252 { + r * x * -x +} + #[cfg(test)] mod tests { - use super::{factorial, init_dict, fib, init_array, search}; + use super::{factorial, init_dict, fib, init_array, search, iterate_map}; #[test] fn test_factorial() { @@ -92,4 +100,24 @@ mod tests { let index = search(@array, 4000); assert_eq!(index, 4000, "invalid result"); } + + #[test] + fn test_map_iteration() { + // Initial value. + let mut x = 1234567890123456789012345678901234567890; + + // Iterate the map. + let mut i = 15000; + let result = loop { + x = iterate_map(4, x); + + if i == 0 { + break x; + } + + i = i - 1; + }; + + assert_eq!(result, 0x12d35a3ae9fe7c56f194b12b34d567a844432acd2b7da993a158c15447a424d, "invalid result"); + } } From 38ec2caa22245e5ae3e72d0b5f712ab1fbc7a45d Mon Sep 17 00:00:00 2001 From: Diego Civini Date: Thu, 21 Aug 2025 15:56:43 -0300 Subject: [PATCH 21/21] Improve script --- Makefile | 4 +++- scripts/benchmarks.sh | 14 ++++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index b1b1e66ee4..cf7c7c72b5 100644 --- a/Makefile +++ b/Makefile @@ -1,2 +1,4 @@ +.PHONY: bench bench: - ./scripts/benchmarks.sh + cargo b --release --bin snforge + ./scripts/benchmarks.sh $(SKIP) diff --git a/scripts/benchmarks.sh b/scripts/benchmarks.sh index 3b394e8a6c..bd00ac23d6 100755 --- a/scripts/benchmarks.sh +++ b/scripts/benchmarks.sh @@ -1,12 +1,22 @@ #!/usr/bin/env bash PROGRAMS_DIR="scarb_programs/" +SKIP=$1 run_bench() { + native_command='../../target/release/snforge test --use-native' + vm_command='../../target/release/snforge test --max-n-steps 100000000' + + # If an argument was passed, it means we should use it as the string for the skip argument in snforge + if [ -n "$SKIP" ]; then + native_command+=" --skip $SKIP" + vm_command+=" --skip $SKIP" + fi + hyperfine \ --warmup 5 \ - '../../target/release/snforge test --use-native' \ - '../../target/release/snforge test --max-n-steps 100000000' + "$native_command" \ + "$vm_command" } for dir in "$PROGRAMS_DIR"/*/; do