diff --git a/.github/workflows/replay.yml b/.github/workflows/replay.yml new file mode 100644 index 00000000000..02c87832aaa --- /dev/null +++ b/.github/workflows/replay.yml @@ -0,0 +1,46 @@ +name: Replay + +on: + push: + branches: + - main + - main-v[0-9].** + pull_request: + +jobs: + clippy: + runs-on: ubuntu-latest + env: + MLIR_SYS_190_PREFIX: /usr/lib/llvm-19/ + LLVM_SYS_191_PREFIX: /usr/lib/llvm-19/ + TABLEGEN_190_PREFIX: /usr/lib/llvm-19/ + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@1.86.0 + with: + components: clippy + - uses: Swatinem/rust-cache@v2 + - name: Add LLVM Debian repository + uses: myci-actions/add-deb-repo@10 + with: + repo: deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-19 main + repo-name: llvm-repo + keys-asc: https://apt.llvm.org/llvm-snapshot.gpg.key + - name: Install lld + run: sudo apt install lld + - name: Install LLVM + run: sudo apt-get install llvm-19 llvm-19-dev llvm-19-runtime clang-19 clang-tools-19 lld-19 libpolly-19-dev libmlir-19-dev mlir-19-tools + - name: Run cargo clippy + run: | + cd crates/blockifier + cargo clippy --all-targets --all-features --no-deps + format: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@nightly + with: + toolchain: nightly-2023-10-19 + components: rustfmt + - name: Run cargo fmt + run: cargo +nightly-2023-10-19 fmt --all -- --check diff --git a/Cargo.lock b/Cargo.lock index 59ed1780558..155efd472f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3563,6 +3563,7 @@ dependencies = [ "cached", "cairo-lang-casm", "cairo-lang-runner", + "cairo-lang-sierra", "cairo-lang-starknet-classes", "cairo-lang-utils", "cairo-native", @@ -3593,6 +3594,7 @@ dependencies = [ "serde", "serde_json", "sha2", + "sierra-emu", "starknet-types-core", "starknet_api", "strum 0.25.0", @@ -3685,6 +3687,12 @@ dependencies = [ "syn 2.0.110", ] +[[package]] +name = "boxcar" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36f64beae40a84da1b4b26ff2761a5b895c12adc41dc25aaee1c4f2bbfe97a6e" + [[package]] name = "bs58" version = "0.5.1" @@ -3811,24 +3819,24 @@ checksum = "ade8366b8bd5ba243f0a58f036cc0ca8a2f069cff1a2351ef1cac6b083e16fc0" [[package]] name = "cairo-lang-casm" -version = "2.12.3" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d1d84a85b59c753aa4a7f0c455a5c815e0aebb89faf0c8ab366b0d87c0bb934" +checksum = "ee2dcadc8a25455272821626d5a4704f5ff78e6338e2f2a51ac4424cd4c007da" dependencies = [ "cairo-lang-utils", "indoc 2.0.7", "num-bigint", "num-traits", "parity-scale-codec", - "schemars 0.8.22", + "schemars 1.1.0", "serde", ] [[package]] name = "cairo-lang-compiler" -version = "2.12.3" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a5cbeb4e134cf29c63d18a235beae3f124bef2824ec45d09d6e18a0c334e509" +checksum = "6ad960dcff2153e42f1bf51c4ffb5900b73a42e3eeab5ad8c4ab589560aa819a" dependencies = [ "anyhow", "cairo-lang-defs", @@ -3845,7 +3853,7 @@ dependencies = [ "cairo-lang-utils", "indoc 2.0.7", "rayon", - "rust-analyzer-salsa", + "salsa", "semver 1.0.27", "smol_str", "thiserror 2.0.17", @@ -3853,18 +3861,20 @@ dependencies = [ [[package]] name = "cairo-lang-debug" -version = "2.12.3" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa5311e1c31d413f3fa34e40e48b662c19151f0fb4b10467d627a52c93eae918" +checksum = "fe4e21147bb85923a0e32ea3365aedfd7270ba5546f109af3e47d30adda00de8" dependencies = [ "cairo-lang-utils", + "id-arena", + "salsa", ] [[package]] name = "cairo-lang-defs" -version = "2.12.3" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "872feccf7b8f70ed5d74c40548bf974fbcc5069b2ea1ae15a9b8f1ab911c536b" +checksum = "ad1ef62d7d2e73c4f397f5799ddb0e504eeabab92e8b78f762df8928c5af987a" dependencies = [ "bincode", "cairo-lang-debug", @@ -3874,30 +3884,30 @@ dependencies = [ "cairo-lang-syntax", "cairo-lang-utils", "itertools 0.14.0", - "rust-analyzer-salsa", + "salsa", "serde", - "smol_str", "typetag", "xxhash-rust", ] [[package]] name = "cairo-lang-diagnostics" -version = "2.12.3" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d0e7c551a634708366af3003176f2f9cdea56fd4a91c834ddd802030366f6a5" +checksum = "1591412d6f437719f45d31c3d015ced1532872a437126dc2c3fbcf0697c1ff85" dependencies = [ "cairo-lang-debug", "cairo-lang-filesystem", "cairo-lang-utils", "itertools 0.14.0", + "salsa", ] [[package]] name = "cairo-lang-eq-solver" -version = "2.12.3" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed04fc3f52d68157f359257c477e30f68dec36bbf568c85d567812583cd5f9c8" +checksum = "8ea391a08d10de26ddb3796d07c34f6685873534df7f0d55a3674500fecc9e53" dependencies = [ "cairo-lang-utils", "good_lp", @@ -3905,25 +3915,26 @@ dependencies = [ [[package]] name = "cairo-lang-filesystem" -version = "2.12.3" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca1835a43a00a90d5cd4ca3f6bb9178ec450d55458e8b56ac34ca1d6d0ccf58f" +checksum = "8baf770719b534cbead72e4a5cf25bf39c4363f887cb960d0368e4a6081a9083" dependencies = [ "cairo-lang-debug", "cairo-lang-utils", + "itertools 0.14.0", "path-clean", - "rust-analyzer-salsa", + "salsa", "semver 1.0.27", "serde", "smol_str", - "toml 0.8.23", + "toml 0.9.8", ] [[package]] name = "cairo-lang-formatter" -version = "2.12.3" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bd0736456004f1d334bad5b366c6933c4b856a23a5dfade96cfe0a1c5eb3ddb" +checksum = "a2628a472dbfe797c1eaaa565f23b2d856f0786cace42afa333b12d3be802dbf" dependencies = [ "anyhow", "cairo-lang-diagnostics", @@ -3934,15 +3945,16 @@ dependencies = [ "diffy", "ignore", "itertools 0.14.0", + "salsa", "serde", "thiserror 2.0.17", ] [[package]] name = "cairo-lang-lowering" -version = "2.12.3" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd2e1d66c241fba4f3dc43e42956001940298fb4ea5970acfc8b2db8bf4b6629" +checksum = "17076bee213e2d10db6132972f19c0842530d3c14fe5376d0b10f9cc7b692a0c" dependencies = [ "assert_matches", "bincode", @@ -3950,26 +3962,28 @@ dependencies = [ "cairo-lang-defs", "cairo-lang-diagnostics", "cairo-lang-filesystem", - "cairo-lang-parser", "cairo-lang-proc-macros", "cairo-lang-semantic", "cairo-lang-syntax", "cairo-lang-utils", "id-arena", + "indent", "itertools 0.14.0", "log", "num-bigint", "num-integer", "num-traits", - "rust-analyzer-salsa", + "salsa", "serde", + "starknet-types-core", + "thiserror 2.0.17", ] [[package]] name = "cairo-lang-parser" -version = "2.12.3" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15c3ab263d4afd34a002dc0e37f9bacca734aa133dbbb8540651d28308977a68" +checksum = "31d3e38a2a928d51ad10d6b8e0315d0000997ec5c935f94f675a6c49d7a2c329" dependencies = [ "cairo-lang-diagnostics", "cairo-lang-filesystem", @@ -3981,16 +3995,15 @@ dependencies = [ "itertools 0.14.0", "num-bigint", "num-traits", - "rust-analyzer-salsa", - "smol_str", + "salsa", "unescaper", ] [[package]] name = "cairo-lang-plugins" -version = "2.12.3" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "566059584384c12fa598ae0e0509fd3d12b3985a25872de22e37245c4bc5762c" +checksum = "34207037fc174e8374261957f7aa320289addccd15eb933c7f4231765e3c3863" dependencies = [ "cairo-lang-defs", "cairo-lang-diagnostics", @@ -4001,8 +4014,7 @@ dependencies = [ "indent", "indoc 2.0.7", "itertools 0.14.0", - "rust-analyzer-salsa", - "smol_str", + "salsa", ] [[package]] @@ -4013,33 +4025,34 @@ checksum = "123ac0ecadf31bacae77436d72b88fa9caef2b8e92c89ce63a125ae911a12fae" [[package]] name = "cairo-lang-proc-macros" -version = "2.12.3" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61599d8cac760505d1913fa5d7dddcf019f22d47f0748ff66b1b58afe1858b62" +checksum = "5239f9c57aeccca184f2743d8861c8cf68d3a5e99b10967cb6ace6c9652fb578" dependencies = [ "cairo-lang-debug", "quote", + "salsa", "syn 2.0.110", ] [[package]] name = "cairo-lang-project" -version = "2.12.3" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99635e2569cebc31583110b417e6a410990a494c7d56998f2be0a169a1158456" +checksum = "dd5794bc799aa27565112ab2fb3f935921acb21cc1736f44e06404ce4d2c70df" dependencies = [ "cairo-lang-filesystem", "cairo-lang-utils", "serde", "thiserror 2.0.17", - "toml 0.8.23", + "toml 0.9.8", ] [[package]] name = "cairo-lang-runnable-utils" -version = "2.12.3" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f747c3d433ec5e82576e59852fd8c86a802fefe55e7bdbb9c0db61adb1a40e7b" +checksum = "cf287b4385ec16ba16e659d073aa78bb34ed4453e1fe4ac5302339217d741904" dependencies = [ "cairo-lang-casm", "cairo-lang-sierra", @@ -4055,9 +4068,9 @@ dependencies = [ [[package]] name = "cairo-lang-runner" -version = "2.12.3" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40a9ab4bb286d641463b2253070c145c53ff7e71f29cda2a49915f79ff7db927" +checksum = "093a2f39137bf3921d0521297b5adb1ef3c409cd458d3aaec1e68b6e66322ce3" dependencies = [ "ark-ff 0.5.0", "ark-secp256k1 0.5.0", @@ -4071,24 +4084,27 @@ dependencies = [ "cairo-lang-starknet", "cairo-lang-utils", "cairo-vm", + "clap", "itertools 0.14.0", "keccak", "num-bigint", "num-integer", "num-traits", "rand 0.9.2", + "salsa", + "serde", "sha2", - "smol_str", "starknet-types-core", "thiserror 2.0.17", ] [[package]] name = "cairo-lang-semantic" -version = "2.12.3" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf1e01333b127fa3733f2f93b3febc45219ef55b807d196f298cadea6ad8fe44" +checksum = "e7cbd123cc8d900642f4345df4a95c5380447e66fa538c3be9d544deea5a480b" dependencies = [ + "bincode", "cairo-lang-debug", "cairo-lang-defs", "cairo-lang-diagnostics", @@ -4104,22 +4120,23 @@ dependencies = [ "itertools 0.14.0", "num-bigint", "num-traits", - "rust-analyzer-salsa", + "salsa", + "serde", "sha3", - "smol_str", - "toml 0.8.23", + "starknet-types-core", + "toml 0.9.8", ] [[package]] name = "cairo-lang-sierra" -version = "2.12.3" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "300655046f505cf806a918918e5397b20c22b579d78c2ef09bc7d4d59fd733be" +checksum = "92c76c30c4a8fbe235bc44c11a458fc6ad9a756245e11dbb6480b92db4b2987a" dependencies = [ "anyhow", "cairo-lang-utils", "const-fnv1a-hash", - "convert_case 0.8.0", + "convert_case 0.9.0", "derivative", "itertools 0.14.0", "lalrpop 0.22.2", @@ -4128,7 +4145,6 @@ dependencies = [ "num-integer", "num-traits", "regex", - "rust-analyzer-salsa", "serde", "serde_json", "sha3", @@ -4139,9 +4155,9 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-ap-change" -version = "2.12.3" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c51190f463ac9f7d4a2ce0e0345cfc92334589811a7114eeeec84029999d7f1" +checksum = "b0e834cfadeda301c005acbcfd17e43b6515a85c7963d6e08e37668d6f6e5a1f" dependencies = [ "cairo-lang-eq-solver", "cairo-lang-sierra", @@ -4155,9 +4171,9 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-gas" -version = "2.12.3" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0d0f038acd79aedcadad4ad2ad928b0881c4e96a2d9ad0e0b3173a6111f313" +checksum = "69137101e55f87b5eb799a1ea6005577e952323564cb978baa80ed3e6a922b7f" dependencies = [ "cairo-lang-eq-solver", "cairo-lang-sierra", @@ -4171,23 +4187,22 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-generator" -version = "2.12.3" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bc8d2a89273ba24529319982a4a7833f2a6c4a87752baea2bc70ceb4b3285b7" +checksum = "93fc200e4664cee28df3c0a6379b999214dd82a0f8d161aafe77a2b4ffc06f3d" dependencies = [ "cairo-lang-debug", "cairo-lang-defs", "cairo-lang-diagnostics", "cairo-lang-filesystem", "cairo-lang-lowering", - "cairo-lang-parser", "cairo-lang-semantic", "cairo-lang-sierra", "cairo-lang-syntax", "cairo-lang-utils", "itertools 0.14.0", "num-traits", - "rust-analyzer-salsa", + "salsa", "serde", "serde_json", "smol_str", @@ -4195,9 +4210,9 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-to-casm" -version = "2.12.3" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c852277442b2d8ca9741cdc8ccb737c6ad381d300ab4e2d982a98ba40e5f5b6" +checksum = "1c4563e2dbb25d2edeeb1cd12749fb22d3284c18cbbdb23f45032d984e805594" dependencies = [ "assert_matches", "cairo-lang-casm", @@ -4216,9 +4231,9 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-type-size" -version = "2.12.3" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "265aa8daaa94cc4d5e135a82c0bbe7d28d2c0fbc612332903dbf1a68ed15978f" +checksum = "d029f4226d5d5746c38194bd30928387c8d8ccd52099325233998e91f7254c4a" dependencies = [ "cairo-lang-sierra", "cairo-lang-utils", @@ -4226,9 +4241,9 @@ dependencies = [ [[package]] name = "cairo-lang-starknet" -version = "2.12.3" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "deb8bf3ccf8fe1f910291d388a2351b6f40ad32be07bdbd3a628e103387b1a48" +checksum = "3930ec68111280fd82023d186ebe505570f76606b9758cf227d998ebf0bc93ec" dependencies = [ "anyhow", "cairo-lang-compiler", @@ -4248,9 +4263,9 @@ dependencies = [ "indent", "indoc 2.0.7", "itertools 0.14.0", + "salsa", "serde", "serde_json", - "smol_str", "starknet-types-core", "thiserror 2.0.17", "typetag", @@ -4258,15 +4273,16 @@ dependencies = [ [[package]] name = "cairo-lang-starknet-classes" -version = "2.12.3" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4839b63927954a7c3d018fd012ce0bea256db205b85ee45df27fb1e90cb10e02" +checksum = "65be3e911c6e2ee521b6ae5d9ed1624462ae91aeb8a3ddce2f196ab465db8e7a" dependencies = [ "cairo-lang-casm", "cairo-lang-sierra", "cairo-lang-sierra-to-casm", + "cairo-lang-sierra-type-size", "cairo-lang-utils", - "convert_case 0.8.0", + "convert_case 0.9.0", "itertools 0.14.0", "num-bigint", "num-integer", @@ -4281,39 +4297,70 @@ dependencies = [ [[package]] name = "cairo-lang-syntax" -version = "2.12.3" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f83d5b0213ddab04090f4a10d009ff3428a0d6e289f4fea31798210d60d5cb" +checksum = "8044a1723f281c7f491466aedee7c5c8ae3a43e90f43e9a33ba44cd229af945c" dependencies = [ "cairo-lang-debug", "cairo-lang-filesystem", "cairo-lang-primitive-token", + "cairo-lang-proc-macros", "cairo-lang-utils", "num-bigint", "num-traits", - "rust-analyzer-salsa", + "salsa", "serde", - "smol_str", "unescaper", + "vector-map", ] [[package]] name = "cairo-lang-syntax-codegen" -version = "2.12.3" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d00ae64466774b6e34a91c4a66202778b17ef5a844a6f668436e28d71ccb9b2" +checksum = "6c0cd642c4b3d2412c253c440a27958a89ca62ff630f492f354bf43d7548de94" dependencies = [ "genco", "xshell", ] +[[package]] +name = "cairo-lang-test-plugin" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b7640a460ebdf175a93cd0cbdf91c99ef2b4142c460ff829c1dc52d8642ff6b" +dependencies = [ + "anyhow", + "cairo-lang-compiler", + "cairo-lang-debug", + "cairo-lang-defs", + "cairo-lang-filesystem", + "cairo-lang-lowering", + "cairo-lang-parser", + "cairo-lang-semantic", + "cairo-lang-sierra", + "cairo-lang-sierra-generator", + "cairo-lang-starknet", + "cairo-lang-starknet-classes", + "cairo-lang-syntax", + "cairo-lang-utils", + "indoc 2.0.7", + "itertools 0.14.0", + "num-bigint", + "num-traits", + "salsa", + "serde", + "starknet-types-core", +] + [[package]] name = "cairo-lang-test-utils" -version = "2.12.3" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebbd4ebcd82ab07fba3d376a6aa992aa552fcb7f051736f6b5a2122381754bdb" +checksum = "3f8d92174190e8654f4354c4869d47a21547e2192421b5a1111a6afcdb061e67" dependencies = [ "cairo-lang-formatter", + "cairo-lang-proc-macros", "cairo-lang-utils", "colored 3.0.0", "log", @@ -4322,26 +4369,30 @@ dependencies = [ [[package]] name = "cairo-lang-utils" -version = "2.12.3" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cca315cce0937801a772bee5fe92cca28b8172421bdd2f67c96e8288a0dcfb9f" +checksum = "41e7dab0d9fb41e05d0dc3fdef607dfae2fe0e820d086f1d40303260cfdb86ec" dependencies = [ - "hashbrown 0.15.5", + "hashbrown 0.16.0", "indexmap 2.12.0", "itertools 0.14.0", "num-bigint", "num-traits", "parity-scale-codec", - "schemars 0.8.22", + "salsa", + "schemars 1.1.0", "serde", "smol_str", + "tracing", + "tracing-log", + "tracing-subscriber", + "vector-map", ] [[package]] name = "cairo-native" version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19404b3af952f1f8f1fcb68c58eafc06d5255002dc7a7c81c800676a0779004a" +source = "git+https://github.com/lambdaclass/cairo_native.git?rev=53371a953b8db9c8bc020e141591853a666cdcf3#53371a953b8db9c8bc020e141591853a666cdcf3" dependencies = [ "aquamarine", "ark-ec 0.5.0", @@ -4349,11 +4400,13 @@ dependencies = [ "ark-secp256k1 0.5.0", "ark-secp256r1 0.5.0", "bumpalo", + "cairo-lang-lowering", "cairo-lang-runner", "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-classes", "cairo-lang-utils", "educe 0.5.11", @@ -4372,6 +4425,7 @@ dependencies = [ "serde", "serde_json", "sha2", + "sierra-emu", "starknet-curve", "starknet-types-core", "tempfile", @@ -4819,9 +4873,9 @@ dependencies = [ [[package]] name = "convert_case" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baaaa0ecca5b51987b9423ccdc971514dd8b0bb7b4060b983d3664dad3f1f89f" +checksum = "db05ffb6856bf0ecdf6367558a76a0e8a77b1713044eb92845c692100ed50190" dependencies = [ "unicode-segmentation", ] @@ -5527,6 +5581,7 @@ dependencies = [ "ff", "generic-array", "group", + "pem-rfc7468", "pkcs8", "rand_core 0.6.4", "sec1", @@ -6397,9 +6452,9 @@ dependencies = [ [[package]] name = "genco" -version = "0.17.10" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a35958104272e516c2a5f66a9d82fba4784d2b585fc1e2358b8f96e15d342995" +checksum = "77ab846431e5d637791b3279e7242fe2b21e11c3d8b4cf6a99f645c5f16ba7c0" dependencies = [ "genco-macros", "relative-path", @@ -6408,9 +6463,9 @@ dependencies = [ [[package]] name = "genco-macros" -version = "0.17.10" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43eaff6bbc0b3a878361aced5ec6a2818ee7c541c5b33b5880dfa9a86c23e9e7" +checksum = "c42a1fe5a699c7f1d36ea6e04ed680a5c787cabff4b610ae3b8954ea3bcefec1" dependencies = [ "proc-macro2", "quote", @@ -6718,6 +6773,8 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" dependencies = [ + "allocator-api2", + "equivalent", "foldhash 0.2.0", "serde", ] @@ -6740,6 +6797,15 @@ dependencies = [ "hashbrown 0.14.5", ] +[[package]] +name = "hashlink" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" +dependencies = [ + "hashbrown 0.15.5", +] + [[package]] name = "hdrhistogram" version = "7.5.4" @@ -7414,6 +7480,15 @@ version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8bb03732005da905c88227371639bf1ad885cc712789c011c31c5fb3ab3ccf02" +[[package]] +name = "intrusive-collections" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "189d0897e4cbe8c75efedf3502c18c887b05046e59d28404d4d8e46cbc4d1e86" +dependencies = [ + "memoffset 0.9.1", +] + [[package]] name = "inventory" version = "0.3.21" @@ -8081,7 +8156,7 @@ dependencies = [ "futures", "futures-timer", "getrandom 0.2.16", - "hashlink", + "hashlink 0.9.1", "hex_fmt", "libp2p-core", "libp2p-identity", @@ -9532,6 +9607,18 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + [[package]] name = "page_size" version = "0.6.0" @@ -10046,6 +10133,15 @@ dependencies = [ "syn 2.0.110", ] +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + [[package]] name = "primitive-types" version = "0.12.2" @@ -10994,35 +11090,6 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" -[[package]] -name = "rust-analyzer-salsa" -version = "0.17.0-pre.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719825638c59fd26a55412a24561c7c5bcf54364c88b9a7a04ba08a6eafaba8d" -dependencies = [ - "indexmap 2.12.0", - "lock_api", - "oorandom", - "parking_lot 0.12.5", - "rust-analyzer-salsa-macros", - "rustc-hash 1.1.0", - "smallvec", - "tracing", - "triomphe", -] - -[[package]] -name = "rust-analyzer-salsa-macros" -version = "0.17.0-pre.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d96498e9684848c6676c399032ebc37c52da95ecbefa83d71ccc53b9f8a4a8e" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "syn 2.0.110", -] - [[package]] name = "rust_decimal" version = "1.39.0" @@ -11219,6 +11286,49 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +[[package]] +name = "salsa" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27956164373aeec733ac24ff1736de8541234e3a8e7e6f916b28175b5752af3b" +dependencies = [ + "boxcar", + "crossbeam-queue", + "crossbeam-utils", + "hashbrown 0.15.5", + "hashlink 0.10.0", + "indexmap 2.12.0", + "intrusive-collections", + "inventory", + "parking_lot 0.12.5", + "portable-atomic", + "rayon", + "rustc-hash 2.1.1", + "salsa-macro-rules", + "salsa-macros", + "smallvec", + "thin-vec", + "tracing", +] + +[[package]] +name = "salsa-macro-rules" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ca3b9d6e47c08b5de4b218e0c5f7ec910b51bce6314e651c8e7b9d154d174da" + +[[package]] +name = "salsa-macros" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6337b62f2968be6b8afa30017d7564ecbde6832ada47ed2261fb14d0fd402ff4" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", + "synstructure", +] + [[package]] name = "salsa20" version = "0.10.2" @@ -11278,7 +11388,7 @@ checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615" dependencies = [ "dyn-clone", "indexmap 1.9.3", - "schemars_derive", + "schemars_derive 0.8.22", "serde", "serde_json", ] @@ -11303,6 +11413,7 @@ checksum = "9558e172d4e8533736ba97870c4b2cd63f84b382a3d6eb063da41b91cce17289" dependencies = [ "dyn-clone", "ref-cast", + "schemars_derive 1.1.0", "serde", "serde_json", ] @@ -11319,6 +11430,18 @@ dependencies = [ "syn 2.0.110", ] +[[package]] +name = "schemars_derive" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301858a4023d78debd2353c7426dc486001bddc91ae31a76fb1f55132f7e2633" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 2.0.110", +] + [[package]] name = "scopeguard" version = "1.2.0" @@ -11506,6 +11629,7 @@ version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ + "indexmap 2.12.0", "itoa", "memchr", "ryu", @@ -11697,6 +11821,48 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "sierra-emu" +version = "0.7.2" +source = "git+https://github.com/lambdaclass/cairo_native.git?rev=53371a953b8db9c8bc020e141591853a666cdcf3#53371a953b8db9c8bc020e141591853a666cdcf3" +dependencies = [ + "cairo-lang-compiler", + "cairo-lang-filesystem", + "cairo-lang-lowering", + "cairo-lang-runner", + "cairo-lang-sierra", + "cairo-lang-sierra-ap-change", + "cairo-lang-sierra-gas", + "cairo-lang-sierra-generator", + "cairo-lang-sierra-to-casm", + "cairo-lang-sierra-type-size", + "cairo-lang-starknet-classes", + "cairo-lang-test-plugin", + "cairo-lang-utils", + "clap", + "generic-array", + "k256", + "keccak", + "num-bigint", + "num-integer", + "num-traits", + "p256", + "rand 0.9.2", + "rayon", + "sec1", + "serde", + "serde_json", + "sha2", + "smallvec", + "starknet-crypto", + "starknet-curve", + "starknet-types-core", + "tempfile", + "thiserror 2.0.17", + "tracing", + "tracing-subscriber", +] + [[package]] name = "signal-hook-registry" version = "1.4.6" @@ -12537,6 +12703,12 @@ dependencies = [ "syn 2.0.110", ] +[[package]] +name = "thin-vec" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "144f754d318415ac792f9d69fc87abbbfc043ce2ef041c60f16ad828f638717d" + [[package]] name = "thiserror" version = "1.0.69" @@ -13113,16 +13285,6 @@ dependencies = [ "syn 2.0.110", ] -[[package]] -name = "triomphe" -version = "0.1.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd69c5aa8f924c7519d6372789a74eac5b94fb0f8fcf0d4a97eb0bfc3e785f39" -dependencies = [ - "serde", - "stable_deref_trait", -] - [[package]] name = "try-lock" version = "0.2.5" @@ -13456,6 +13618,15 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "vector-map" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03b34e878e32c750bb4253be124adb9da1dc93ca5d98c210787badf1e1ccdca7" +dependencies = [ + "serde", +] + [[package]] name = "version_check" version = "0.9.5" diff --git a/Cargo.toml b/Cargo.toml index ca4ebae1e14..2feaf4d5245 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -231,7 +231,8 @@ cairo-lang-sierra = "2.12.3" cairo-lang-sierra-to-casm = "2.12.3" cairo-lang-starknet-classes = "2.12.3" cairo-lang-utils = "2.12.3" -cairo-native = "0.7.2" +cairo-native = { git = "https://github.com/lambdaclass/cairo_native.git", rev = "53371a953b8db9c8bc020e141591853a666cdcf3" } +sierra-emu = { git = "https://github.com/lambdaclass/cairo_native.git", rev = "53371a953b8db9c8bc020e141591853a666cdcf3" } cairo-vm = "2.5.0" camelpaste = "0.1.0" chrono = "0.4.26" diff --git a/crates/blockifier/Cargo.toml b/crates/blockifier/Cargo.toml index a524d77eab2..d4b66f5be88 100644 --- a/crates/blockifier/Cargo.toml +++ b/crates/blockifier/Cargo.toml @@ -10,11 +10,14 @@ description = "The transaction-executing component in the Starknet sequencer." workspace = true [features] +with-libfunc-profiling = [ "cairo_native", "cairo-native/with-libfunc-profiling" ] +with-trace-dump = [ "cairo_native", "cairo-native/with-trace-dump" ] cairo_native = [ "blockifier_test_utils/cairo_native", "dep:apollo_compilation_utils", "dep:apollo_compile_to_native", "dep:cairo-native", + "dep:sierra-emu", ] mocks = [] native_blockifier = [] @@ -23,6 +26,7 @@ reexecution = ["transaction_serde"] testing = ["blockifier_test_utils", "rand", "rstest", "rstest_reuse", "starknet_api/testing"] tracing = [] transaction_serde = [] +only-native = ["cairo_native"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -44,7 +48,9 @@ cairo-lang-casm = { workspace = true, features = ["parity-scale-codec"] } cairo-lang-runner.workspace = true cairo-lang-starknet-classes.workspace = true cairo-lang-utils.workspace = true +cairo-lang-sierra.workspace = true cairo-native = { workspace = true, optional = true } +sierra-emu = { workspace = true, optional = true } cairo-vm.workspace = true derive_more.workspace = true indexmap.workspace = true diff --git a/crates/blockifier/src/execution/call_info.rs b/crates/blockifier/src/execution/call_info.rs index 15dfa772b8a..5019aa7e274 100644 --- a/crates/blockifier/src/execution/call_info.rs +++ b/crates/blockifier/src/execution/call_info.rs @@ -96,6 +96,7 @@ impl EventSummary { } } +#[cfg_attr(feature = "transaction_serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Copy, Debug, Default, derive_more::AddAssign, PartialEq)] pub struct CallSummary { pub n_calls: u64, @@ -104,6 +105,7 @@ pub struct CallSummary { pub type BuiltinCounterMap = HashMap; +#[cfg_attr(feature = "transaction_serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug, Default, PartialEq)] pub struct ExecutionSummary { pub charged_resources: ChargedResources, @@ -237,6 +239,8 @@ pub struct CallInfo { pub tracked_resource: TrackedResource, // Additional information gathered during execution. + pub time: std::time::Duration, + pub call_counter: usize, pub storage_access_tracker: StorageAccessTracker, // Tracks how many times each builtin was called during execution (excluding inner calls). // Used by the bouncer to decide when to close a block. diff --git a/crates/blockifier/src/execution/deprecated_entry_point_execution.rs b/crates/blockifier/src/execution/deprecated_entry_point_execution.rs index 8ac6d257754..135faf9d328 100644 --- a/crates/blockifier/src/execution/deprecated_entry_point_execution.rs +++ b/crates/blockifier/src/execution/deprecated_entry_point_execution.rs @@ -290,6 +290,8 @@ pub fn finalize_execution( }, builtin_counters: vm_resources_without_inner_calls.prover_builtins(), syscalls_usage: syscall_handler.syscalls_usage, + time: std::time::Duration::default(), + call_counter: Default::default(), }) } diff --git a/crates/blockifier/src/execution/entry_point.rs b/crates/blockifier/src/execution/entry_point.rs index ac6a088d833..1fae8486b3d 100644 --- a/crates/blockifier/src/execution/entry_point.rs +++ b/crates/blockifier/src/execution/entry_point.rs @@ -328,6 +328,9 @@ pub struct EntryPointExecutionContext { // Used to support charging for gas consumed in blockifier revert flow. pub sierra_gas_revert_tracker: SierraGasRevertTracker, + + // Counts the nomber of calls executed + pub call_counter: usize, } impl EntryPointExecutionContext { @@ -348,6 +351,7 @@ impl EntryPointExecutionContext { tracked_resource_stack: vec![], revert_infos: ExecutionRevertInfo(vec![]), sierra_gas_revert_tracker, + call_counter: 0, } } diff --git a/crates/blockifier/src/execution/entry_point_execution.rs b/crates/blockifier/src/execution/entry_point_execution.rs index eebf48a5457..2eee159e9d1 100644 --- a/crates/blockifier/src/execution/entry_point_execution.rs +++ b/crates/blockifier/src/execution/entry_point_execution.rs @@ -484,6 +484,8 @@ pub fn finalize_execution( storage_access_tracker: syscall_handler_base.storage_access_tracker, builtin_counters: vm_resources_without_inner_calls.prover_builtins(), syscalls_usage: syscall_handler_base.syscalls_usage, + time: std::time::Duration::default(), + call_counter: Default::default(), }) } diff --git a/crates/blockifier/src/execution/execution_utils.rs b/crates/blockifier/src/execution/execution_utils.rs index c808d7ddf80..64546a6679a 100644 --- a/crates/blockifier/src/execution/execution_utils.rs +++ b/crates/blockifier/src/execution/execution_utils.rs @@ -120,7 +120,11 @@ pub fn execute_entry_point_call( state: &mut dyn State, context: &mut EntryPointExecutionContext, ) -> EntryPointExecutionResult { - match compiled_class { + let current_call_counter = context.call_counter; + context.call_counter += 1; + let pre_time = std::time::Instant::now(); + + let mut result = match compiled_class { RunnableCompiledClass::V0(compiled_class) => { deprecated_entry_point_execution::execute_entry_point_call( call, @@ -134,7 +138,9 @@ pub fn execute_entry_point_call( } #[cfg(feature = "cairo_native")] RunnableCompiledClass::V1Native(compiled_class) => { - if context.tracked_resource_stack.last() == Some(&TrackedResource::CairoSteps) { + if context.tracked_resource_stack.last() == Some(&TrackedResource::CairoSteps) + && !cfg!(feature = "only-native") + { // We cannot run native with cairo steps as the tracked resources (it's a vm // resouorce). entry_point_execution::execute_entry_point_call( @@ -152,7 +158,11 @@ pub fn execute_entry_point_call( ) } } - } + }?; + + result.time = pre_time.elapsed(); + result.call_counter = current_call_counter; + Ok(result) } pub fn update_remaining_gas(remaining_gas: &mut u64, call_info: &CallInfo) { diff --git a/crates/blockifier/src/execution/native.rs b/crates/blockifier/src/execution/native.rs index 8b24ff59652..be1eadd45e7 100644 --- a/crates/blockifier/src/execution/native.rs +++ b/crates/blockifier/src/execution/native.rs @@ -1,5 +1,6 @@ pub mod contract_class; pub mod entry_point_execution; +pub mod executor; pub mod syscall_handler; pub mod utils; diff --git a/crates/blockifier/src/execution/native/contract_class.rs b/crates/blockifier/src/execution/native/contract_class.rs index d7c6999fac9..a2ca15ddc4a 100644 --- a/crates/blockifier/src/execution/native/contract_class.rs +++ b/crates/blockifier/src/execution/native/contract_class.rs @@ -10,6 +10,7 @@ use starknet_types_core::felt::Felt; use crate::execution::contract_class::{CompiledClassV1, EntryPointV1, NestedFeltCounts}; use crate::execution::entry_point::EntryPointTypeAndSelector; use crate::execution::errors::PreExecutionError; +use crate::execution::native::executor::ContractExecutor; #[derive(Clone, Debug, PartialEq, Eq)] pub struct NativeCompiledClassV1(pub Arc); impl Deref for NativeCompiledClassV1 { @@ -34,6 +35,11 @@ impl NativeCompiledClassV1 { Self(Arc::new(contract)) } + pub fn new_2(executor: ContractExecutor, casm: CompiledClassV1) -> NativeCompiledClassV1 { + let contract = NativeCompiledClassV1Inner::new_2(executor, casm); + + Self(Arc::new(contract)) + } pub fn get_entry_point( &self, @@ -71,12 +77,16 @@ impl HashableCompiledClass for NativeCompiledCla #[derive(Debug)] pub struct NativeCompiledClassV1Inner { - pub executor: AotContractExecutor, + pub executor: ContractExecutor, casm: CompiledClassV1, } impl NativeCompiledClassV1Inner { fn new(executor: AotContractExecutor, casm: CompiledClassV1) -> Self { + let executor = executor.into(); + NativeCompiledClassV1Inner { executor, casm } + } + fn new_2(executor: ContractExecutor, casm: CompiledClassV1) -> Self { NativeCompiledClassV1Inner { executor, casm } } } diff --git a/crates/blockifier/src/execution/native/entry_point_execution.rs b/crates/blockifier/src/execution/native/entry_point_execution.rs index 5d3a597e457..181afa6ec5d 100644 --- a/crates/blockifier/src/execution/native/entry_point_execution.rs +++ b/crates/blockifier/src/execution/native/entry_point_execution.rs @@ -115,6 +115,8 @@ fn create_callinfo( tracked_resource: TrackedResource::SierraGas, builtin_counters, syscalls_usage: syscall_handler.base.syscalls_usage, + time: std::time::Duration::default(), + call_counter: Default::default(), }) } diff --git a/crates/blockifier/src/execution/native/executor.rs b/crates/blockifier/src/execution/native/executor.rs new file mode 100644 index 00000000000..6648f520cfe --- /dev/null +++ b/crates/blockifier/src/execution/native/executor.rs @@ -0,0 +1,665 @@ +use std::fs::{self, File}; +use std::io::Write; +use std::path::PathBuf; +use std::sync::atomic::AtomicU64; +use std::sync::Arc; + +use cairo_lang_sierra::program::Program; +use cairo_lang_starknet_classes::compiler_version::VersionId; +use cairo_lang_starknet_classes::contract_class::ContractEntryPoints; +use cairo_native::execution_result::ContractExecutionResult; +use cairo_native::executor::AotContractExecutor; +use cairo_native::starknet::StarknetSyscallHandler; +use cairo_native::utils::BuiltinCosts; +use itertools::Itertools; +use sierra_emu::VirtualMachine; +use starknet_types_core::felt::Felt; +#[cfg(feature = "with-libfunc-profiling")] +use { + cairo_lang_sierra::ids::ConcreteLibfuncId, + cairo_native::metadata::profiler::LibfuncProfileData, + std::collections::HashMap, + std::sync::{LazyLock, Mutex}, +}; + +use super::syscall_handler::NativeSyscallHandler; +#[cfg(feature = "with-libfunc-profiling")] +pub struct EntrypointProfile { + pub class_hash: Felt, + pub selector: Felt, + // Map a libfunc id to its respective profile + pub profile: HashMap, + pub program: Program, +} + +#[cfg(feature = "with-libfunc-profiling")] +pub struct TransactionProfile { + pub block_number: u64, + pub tx_hash: String, + pub entrypoint_profiles: Vec, +} + +#[cfg(feature = "with-libfunc-profiling")] +// Map a transaction hash to its profile +type ProfilesByBlockTx = HashMap; + +#[cfg(feature = "with-libfunc-profiling")] +pub static LIBFUNC_PROFILES_MAP: LazyLock> = + LazyLock::new(|| Mutex::new(HashMap::new())); + +#[derive(Debug)] +pub enum ContractExecutor { + Aot(AotContractExecutor), + Emu((Arc, ContractEntryPoints, VersionId)), + // must use a different variant as we need `Program` for trace feature + #[cfg(any(feature = "with-trace-dump", feature = "with-libfunc-profiling"))] + AotWithProgram((AotContractExecutor, Program)), +} + +impl From for ContractExecutor { + fn from(value: AotContractExecutor) -> Self { + Self::Aot(value) + } +} +impl From<(Arc, ContractEntryPoints, VersionId)> for ContractExecutor { + fn from(value: (Arc, ContractEntryPoints, VersionId)) -> Self { + Self::Emu(value) + } +} + +impl ContractExecutor { + pub fn run( + &self, + selector: Felt, + args: &[Felt], + gas: u64, + builtin_costs: Option, + mut syscall_handler: &mut NativeSyscallHandler<'_>, + ) -> cairo_native::error::Result { + match self { + ContractExecutor::Aot(aot_contract_executor) => { + aot_contract_executor.run(selector, args, gas, builtin_costs, syscall_handler) + } + ContractExecutor::Emu((program, entrypoints, version)) => { + let mut virtual_machine = + VirtualMachine::new_starknet(program.to_owned(), entrypoints, *version); + + let builtin_costs = builtin_costs.map(|builtin_costs| sierra_emu::BuiltinCosts { + r#const: builtin_costs.r#const, + pedersen: builtin_costs.pedersen, + bitwise: builtin_costs.bitwise, + ecop: builtin_costs.ecop, + poseidon: builtin_costs.poseidon, + add_mod: builtin_costs.add_mod, + mul_mod: builtin_costs.mul_mod, + }); + + let args = args.to_owned(); + virtual_machine.call_contract(selector, gas, args, builtin_costs); + + let result = if cfg!(feature = "with-trace-dump") { + static COUNTER: AtomicU64 = AtomicU64::new(0); + let counter = COUNTER.fetch_add(1, std::sync::atomic::Ordering::Relaxed); + + let trace = virtual_machine.run_with_trace(&mut syscall_handler); + + let trace_path = PathBuf::from(format!("traces/emu/{counter}.json")); + let trace_parent_path = trace_path.parent().unwrap(); + fs::create_dir_all(trace_parent_path).unwrap(); + let trace_file = File::create(&trace_path).unwrap(); + serde_json::to_writer_pretty(trace_file, &trace).unwrap(); + + let sierra_path = PathBuf::from(format!("traces/{counter}.sierra")); + let mut sierra_file = File::create(&sierra_path).unwrap(); + write!(sierra_file, "{}", program).unwrap(); + + sierra_emu::ContractExecutionResult::from_trace(&trace).unwrap() + } else { + virtual_machine.run(&mut syscall_handler).unwrap() + }; + + Ok(ContractExecutionResult { + remaining_gas: result.remaining_gas, + failure_flag: result.failure_flag, + return_values: result.return_values, + error_msg: result.error_msg, + builtin_stats: Default::default(), + }) + } + #[cfg(any(feature = "with-trace-dump", feature = "with-libfunc-profiling"))] + ContractExecutor::AotWithProgram((executor, program)) => { + #[cfg(feature = "with-trace-dump")] + use { + cairo_lang_sierra::program_registry::ProgramRegistry, + cairo_native::metadata::trace_dump::trace_dump_runtime::{ + TraceDump, + TRACE_DUMP, + }, + cairo_native::metadata::trace_dump::TraceBinding, + }; + #[cfg(feature = "with-libfunc-profiling")] + use { + cairo_native::metadata::profiler::ProfilerBinding, + cairo_native::metadata::profiler::{ProfilerImpl, LIBFUNC_PROFILE}, + }; + + static COUNTER: AtomicU64 = AtomicU64::new(0); + + #[cfg(feature = "with-trace-dump")] + let trace_dump_trace_id: &mut u64; + #[cfg(feature = "with-trace-dump")] + let trace_dump_old_trace_id: u64; + + #[cfg(feature = "with-libfunc-profiling")] + let libfunc_profiling_trace_id: &mut u64; + #[cfg(feature = "with-libfunc-profiling")] + let libfunc_profiling_old_trace_id: u64; + #[cfg(feature = "with-libfunc-profiling")] + let class_hash = *syscall_handler.base.call.class_hash; + #[cfg(feature = "with-libfunc-profiling")] + let tx_hash = syscall_handler + .base + .context + .tx_context + .tx_info + .transaction_hash() + .to_hex_string(); + #[cfg(feature = "with-libfunc-profiling")] + let block_number = + syscall_handler.base.context.tx_context.block_context.block_info.block_number.0; + + let counter = COUNTER.fetch_add(1, std::sync::atomic::Ordering::Relaxed); + + #[cfg(feature = "with-trace-dump")] + { + TRACE_DUMP + .lock() + .unwrap() + .insert(counter, TraceDump::new(ProgramRegistry::new(program).unwrap())); + + trace_dump_trace_id = unsafe { + let trace_id_ptr = + executor.find_symbol_ptr(TraceBinding::TraceId.symbol()).unwrap(); + trace_id_ptr.cast::().as_mut().unwrap() + }; + + trace_dump_old_trace_id = *trace_dump_trace_id; + *trace_dump_trace_id = counter; + } + + #[cfg(feature = "with-libfunc-profiling")] + { + LIBFUNC_PROFILE.lock().unwrap().insert(counter, ProfilerImpl::new()); + + libfunc_profiling_trace_id = unsafe { + let trace_id_ptr = + executor.find_symbol_ptr(ProfilerBinding::ProfileId.symbol()).unwrap(); + trace_id_ptr.cast::().as_mut().unwrap() + }; + + libfunc_profiling_old_trace_id = *libfunc_profiling_trace_id; + *libfunc_profiling_trace_id = counter; + } + + let result = executor.run(selector, args, gas, builtin_costs, syscall_handler); + + #[cfg(feature = "with-trace-dump")] + { + // Retreive trace dump for current execution + let trace = TRACE_DUMP.lock().unwrap().remove(&counter).unwrap().trace; + + // Save trace dump to file + let trace_path = PathBuf::from(format!("traces/native/{counter}.json")); + let trace_parent_path = trace_path.parent().unwrap(); + fs::create_dir_all(trace_parent_path).unwrap(); + let trace_file = File::create(&trace_path).unwrap(); + serde_json::to_writer_pretty(trace_file, &trace).unwrap(); + + *trace_dump_trace_id = trace_dump_old_trace_id; + } + + #[cfg(feature = "with-libfunc-profiling")] + { + // Retreive profile for current execution + let profile = LIBFUNC_PROFILE.lock().unwrap().remove(&counter).unwrap(); + + let raw_profile = profile.get_profile(program); + + let mut profiles_map = LIBFUNC_PROFILES_MAP.lock().unwrap(); + + let profile = EntrypointProfile { + class_hash, + selector, + profile: raw_profile, + program: program.clone(), + }; + + match profiles_map.get_mut(&tx_hash) { + Some(tx_profile) => { + tx_profile.entrypoint_profiles.push(profile); + } + None => { + let tx_profile = TransactionProfile { + block_number, + tx_hash: tx_hash.clone(), + entrypoint_profiles: vec![profile], + }; + profiles_map.insert(tx_hash, tx_profile); + } + }; + + *libfunc_profiling_trace_id = libfunc_profiling_old_trace_id; + } + + result + } + } + } +} + +// doesn't contain any logic, it calls the underlying sequencer implementation +impl sierra_emu::starknet::StarknetSyscallHandler for &mut NativeSyscallHandler<'_> { + fn get_block_hash( + &mut self, + block_number: u64, + remaining_gas: &mut u64, + ) -> sierra_emu::starknet::SyscallResult { + StarknetSyscallHandler::get_block_hash(self, block_number, remaining_gas) + } + + fn get_execution_info( + &mut self, + remaining_gas: &mut u64, + ) -> sierra_emu::starknet::SyscallResult { + StarknetSyscallHandler::get_execution_info(self, remaining_gas).map(convert_execution_info) + } + + fn get_execution_info_v2( + &mut self, + remaining_gas: &mut u64, + ) -> sierra_emu::starknet::SyscallResult { + StarknetSyscallHandler::get_execution_info_v2(self, remaining_gas) + .map(convert_execution_info_v2) + } + + fn deploy( + &mut self, + class_hash: Felt, + contract_address_salt: Felt, + calldata: Vec, + deploy_from_zero: bool, + remaining_gas: &mut u64, + ) -> sierra_emu::starknet::SyscallResult<(Felt, Vec)> { + StarknetSyscallHandler::deploy( + self, + class_hash, + contract_address_salt, + &calldata, + deploy_from_zero, + remaining_gas, + ) + } + + fn replace_class( + &mut self, + class_hash: Felt, + remaining_gas: &mut u64, + ) -> sierra_emu::starknet::SyscallResult<()> { + StarknetSyscallHandler::replace_class(self, class_hash, remaining_gas) + } + + fn library_call( + &mut self, + class_hash: Felt, + function_selector: Felt, + calldata: Vec, + remaining_gas: &mut u64, + ) -> sierra_emu::starknet::SyscallResult> { + StarknetSyscallHandler::library_call( + self, + class_hash, + function_selector, + &calldata, + remaining_gas, + ) + } + + fn call_contract( + &mut self, + address: Felt, + entry_point_selector: Felt, + calldata: Vec, + remaining_gas: &mut u64, + ) -> sierra_emu::starknet::SyscallResult> { + StarknetSyscallHandler::call_contract( + self, + address, + entry_point_selector, + &calldata, + remaining_gas, + ) + } + + fn storage_read( + &mut self, + address_domain: u32, + address: Felt, + remaining_gas: &mut u64, + ) -> sierra_emu::starknet::SyscallResult { + StarknetSyscallHandler::storage_read(self, address_domain, address, remaining_gas) + } + + fn storage_write( + &mut self, + address_domain: u32, + address: Felt, + value: Felt, + remaining_gas: &mut u64, + ) -> sierra_emu::starknet::SyscallResult<()> { + StarknetSyscallHandler::storage_write(self, address_domain, address, value, remaining_gas) + } + + fn emit_event( + &mut self, + keys: Vec, + data: Vec, + remaining_gas: &mut u64, + ) -> sierra_emu::starknet::SyscallResult<()> { + StarknetSyscallHandler::emit_event(self, &keys, &data, remaining_gas) + } + + fn send_message_to_l1( + &mut self, + to_address: Felt, + payload: Vec, + remaining_gas: &mut u64, + ) -> sierra_emu::starknet::SyscallResult<()> { + StarknetSyscallHandler::send_message_to_l1(self, to_address, &payload, remaining_gas) + } + + fn keccak( + &mut self, + input: Vec, + remaining_gas: &mut u64, + ) -> sierra_emu::starknet::SyscallResult { + StarknetSyscallHandler::keccak(self, &input, remaining_gas).map(convert_u256) + } + + fn secp256k1_new( + &mut self, + x: sierra_emu::starknet::U256, + y: sierra_emu::starknet::U256, + remaining_gas: &mut u64, + ) -> sierra_emu::starknet::SyscallResult> { + StarknetSyscallHandler::secp256k1_new( + self, + convert_from_u256(x), + convert_from_u256(y), + remaining_gas, + ) + .map(|x| x.map(convert_secp_256_k1_point)) + } + + fn secp256k1_add( + &mut self, + p0: sierra_emu::starknet::Secp256k1Point, + p1: sierra_emu::starknet::Secp256k1Point, + remaining_gas: &mut u64, + ) -> sierra_emu::starknet::SyscallResult { + StarknetSyscallHandler::secp256k1_add( + self, + convert_from_secp_256_k1_point(p0), + convert_from_secp_256_k1_point(p1), + remaining_gas, + ) + .map(convert_secp_256_k1_point) + } + + fn secp256k1_mul( + &mut self, + p: sierra_emu::starknet::Secp256k1Point, + m: sierra_emu::starknet::U256, + remaining_gas: &mut u64, + ) -> sierra_emu::starknet::SyscallResult { + StarknetSyscallHandler::secp256k1_mul( + self, + convert_from_secp_256_k1_point(p), + convert_from_u256(m), + remaining_gas, + ) + .map(convert_secp_256_k1_point) + } + + fn secp256k1_get_point_from_x( + &mut self, + x: sierra_emu::starknet::U256, + y_parity: bool, + remaining_gas: &mut u64, + ) -> sierra_emu::starknet::SyscallResult> { + StarknetSyscallHandler::secp256k1_get_point_from_x( + self, + convert_from_u256(x), + y_parity, + remaining_gas, + ) + .map(|x| x.map(convert_secp_256_k1_point)) + } + + fn secp256k1_get_xy( + &mut self, + p: sierra_emu::starknet::Secp256k1Point, + remaining_gas: &mut u64, + ) -> sierra_emu::starknet::SyscallResult<(sierra_emu::starknet::U256, sierra_emu::starknet::U256)> + { + StarknetSyscallHandler::secp256k1_get_xy( + self, + convert_from_secp_256_k1_point(p), + remaining_gas, + ) + .map(|(x, y)| (convert_u256(x), convert_u256(y))) + } + + fn secp256r1_new( + &mut self, + x: sierra_emu::starknet::U256, + y: sierra_emu::starknet::U256, + remaining_gas: &mut u64, + ) -> sierra_emu::starknet::SyscallResult> { + StarknetSyscallHandler::secp256r1_new( + self, + convert_from_u256(x), + convert_from_u256(y), + remaining_gas, + ) + .map(|x| x.map(convert_secp_256_r1_point)) + } + + fn secp256r1_add( + &mut self, + p0: sierra_emu::starknet::Secp256r1Point, + p1: sierra_emu::starknet::Secp256r1Point, + remaining_gas: &mut u64, + ) -> sierra_emu::starknet::SyscallResult { + StarknetSyscallHandler::secp256r1_add( + self, + convert_from_secp_256_r1_point(p0), + convert_from_secp_256_r1_point(p1), + remaining_gas, + ) + .map(convert_secp_256_r1_point) + } + + fn secp256r1_mul( + &mut self, + p: sierra_emu::starknet::Secp256r1Point, + m: sierra_emu::starknet::U256, + remaining_gas: &mut u64, + ) -> sierra_emu::starknet::SyscallResult { + StarknetSyscallHandler::secp256r1_mul( + self, + convert_from_secp_256_r1_point(p), + convert_from_u256(m), + remaining_gas, + ) + .map(convert_secp_256_r1_point) + } + + fn secp256r1_get_point_from_x( + &mut self, + x: sierra_emu::starknet::U256, + y_parity: bool, + remaining_gas: &mut u64, + ) -> sierra_emu::starknet::SyscallResult> { + StarknetSyscallHandler::secp256r1_get_point_from_x( + self, + convert_from_u256(x), + y_parity, + remaining_gas, + ) + .map(|x| x.map(convert_secp_256_r1_point)) + } + + fn secp256r1_get_xy( + &mut self, + p: sierra_emu::starknet::Secp256r1Point, + remaining_gas: &mut u64, + ) -> sierra_emu::starknet::SyscallResult<(sierra_emu::starknet::U256, sierra_emu::starknet::U256)> + { + StarknetSyscallHandler::secp256r1_get_xy( + self, + convert_from_secp_256_r1_point(p), + remaining_gas, + ) + .map(|(x, y)| (convert_u256(x), convert_u256(y))) + } + + fn sha256_process_block( + &mut self, + mut prev_state: [u32; 8], + current_block: [u32; 16], + remaining_gas: &mut u64, + ) -> sierra_emu::starknet::SyscallResult<[u32; 8]> { + StarknetSyscallHandler::sha256_process_block( + self, + &mut prev_state, + ¤t_block, + remaining_gas, + )?; + + Ok(prev_state) + } +} + +// The Sierra Emu and the Native syscall handler have different types (although they are identical). +// The following functions help to convert between them. + +fn convert_u256(x: cairo_native::starknet::U256) -> sierra_emu::starknet::U256 { + sierra_emu::starknet::U256 { lo: x.lo, hi: x.hi } +} + +fn convert_from_u256(x: sierra_emu::starknet::U256) -> cairo_native::starknet::U256 { + cairo_native::starknet::U256 { lo: x.lo, hi: x.hi } +} + +fn convert_secp_256_k1_point( + x: cairo_native::starknet::Secp256k1Point, +) -> sierra_emu::starknet::Secp256k1Point { + sierra_emu::starknet::Secp256k1Point { x: convert_u256(x.x), y: convert_u256(x.y) } +} + +fn convert_from_secp_256_k1_point( + x: sierra_emu::starknet::Secp256k1Point, +) -> cairo_native::starknet::Secp256k1Point { + cairo_native::starknet::Secp256k1Point { + x: convert_from_u256(x.x), + y: convert_from_u256(x.y), + is_infinity: false, + } +} + +fn convert_secp_256_r1_point( + x: cairo_native::starknet::Secp256r1Point, +) -> sierra_emu::starknet::Secp256r1Point { + sierra_emu::starknet::Secp256r1Point { x: convert_u256(x.x), y: convert_u256(x.y) } +} +fn convert_from_secp_256_r1_point( + x: sierra_emu::starknet::Secp256r1Point, +) -> cairo_native::starknet::Secp256r1Point { + cairo_native::starknet::Secp256r1Point { + x: convert_from_u256(x.x), + y: convert_from_u256(x.y), + is_infinity: false, + } +} + +fn convert_execution_info( + x: cairo_native::starknet::ExecutionInfo, +) -> sierra_emu::starknet::ExecutionInfo { + sierra_emu::starknet::ExecutionInfo { + block_info: convert_block_info(x.block_info), + tx_info: convert_tx_info(x.tx_info), + caller_address: x.caller_address, + contract_address: x.contract_address, + entry_point_selector: x.entry_point_selector, + } +} + +fn convert_tx_info(x: cairo_native::starknet::TxInfo) -> sierra_emu::starknet::TxInfo { + sierra_emu::starknet::TxInfo { + version: x.version, + account_contract_address: x.account_contract_address, + max_fee: x.max_fee, + signature: x.signature, + transaction_hash: x.transaction_hash, + chain_id: x.chain_id, + nonce: x.nonce, + } +} + +fn convert_execution_info_v2( + x: cairo_native::starknet::ExecutionInfoV2, +) -> sierra_emu::starknet::ExecutionInfoV2 { + sierra_emu::starknet::ExecutionInfoV2 { + block_info: convert_block_info(x.block_info), + tx_info: convert_tx_v2_info(x.tx_info), + caller_address: x.caller_address, + contract_address: x.contract_address, + entry_point_selector: x.entry_point_selector, + } +} + +fn convert_tx_v2_info(x: cairo_native::starknet::TxV2Info) -> sierra_emu::starknet::TxV2Info { + sierra_emu::starknet::TxV2Info { + version: x.version, + account_contract_address: x.account_contract_address, + max_fee: x.max_fee, + signature: x.signature, + transaction_hash: x.transaction_hash, + chain_id: x.chain_id, + nonce: x.nonce, + resource_bounds: x.resource_bounds.into_iter().map(convert_resource_bounds).collect_vec(), + tip: x.tip, + paymaster_data: x.paymaster_data, + nonce_data_availability_mode: x.nonce_data_availability_mode, + fee_data_availability_mode: x.fee_data_availability_mode, + account_deployment_data: x.account_deployment_data, + } +} + +fn convert_resource_bounds( + resource_bounds: cairo_native::starknet::ResourceBounds, +) -> sierra_emu::starknet::ResourceBounds { + sierra_emu::starknet::ResourceBounds { + resource: resource_bounds.resource, + max_amount: resource_bounds.max_amount, + max_price_per_unit: resource_bounds.max_price_per_unit, + } +} + +fn convert_block_info(x: cairo_native::starknet::BlockInfo) -> sierra_emu::starknet::BlockInfo { + sierra_emu::starknet::BlockInfo { + block_number: x.block_number, + block_timestamp: x.block_timestamp, + sequencer_address: x.sequencer_address, + } +}