diff --git a/Cargo.lock b/Cargo.lock index c8aa13ee71..5299fcfb3f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -572,9 +572,8 @@ checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" [[package]] name = "cairo-lang-casm" -version = "2.19.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15c13d355783b9ff4b54a995a49a639707e32502cac2d886b7ec62b367694c05" +version = "2.19.3" +source = "git+https://github.com/starkware-libs/cairo?branch=ron%2Fdeploy-v2%2Fcompiler#636de0fc36d81b580b8518afd1dcc76582d12507" dependencies = [ "cairo-lang-utils", "indoc", @@ -586,9 +585,8 @@ dependencies = [ [[package]] name = "cairo-lang-compiler" -version = "2.19.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4332bf28b1ccc82f064ed6ed4f287828391d4c5629f8f49ef6ddc3915b56e381" +version = "2.19.3" +source = "git+https://github.com/starkware-libs/cairo?branch=ron%2Fdeploy-v2%2Fcompiler#636de0fc36d81b580b8518afd1dcc76582d12507" dependencies = [ "anyhow", "cairo-lang-defs", @@ -613,9 +611,8 @@ dependencies = [ [[package]] name = "cairo-lang-debug" -version = "2.19.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e58a589f842fd8ae1191530c04b5df490f94fb803bb5ccd96adbfcaba9b3ab1f" +version = "2.19.3" +source = "git+https://github.com/starkware-libs/cairo?branch=ron%2Fdeploy-v2%2Fcompiler#636de0fc36d81b580b8518afd1dcc76582d12507" dependencies = [ "cairo-lang-utils", "id-arena", @@ -624,9 +621,8 @@ dependencies = [ [[package]] name = "cairo-lang-defs" -version = "2.19.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97ef9dc4dfb938a2585100e452e2b6184662bb9bba7042226411fa6bc07cb91" +version = "2.19.3" +source = "git+https://github.com/starkware-libs/cairo?branch=ron%2Fdeploy-v2%2Fcompiler#636de0fc36d81b580b8518afd1dcc76582d12507" dependencies = [ "cairo-lang-debug", "cairo-lang-diagnostics", @@ -635,33 +631,32 @@ dependencies = [ "cairo-lang-proc-macros", "cairo-lang-syntax", "cairo-lang-utils", - "itertools 0.14.0", + "itertools 0.15.0", "postcard", "salsa", "serde", + "thiserror", "typetag", "xxhash-rust", ] [[package]] name = "cairo-lang-diagnostics" -version = "2.19.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0045ae336e51dc4112e1c678591262184ca22e6bda4c759619a6a817a60d967d" +version = "2.19.3" +source = "git+https://github.com/starkware-libs/cairo?branch=ron%2Fdeploy-v2%2Fcompiler#636de0fc36d81b580b8518afd1dcc76582d12507" dependencies = [ "cairo-lang-debug", "cairo-lang-filesystem", "cairo-lang-proc-macros", "cairo-lang-utils", - "itertools 0.14.0", + "itertools 0.15.0", "salsa", ] [[package]] name = "cairo-lang-eq-solver" -version = "2.19.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27f93abccc09808fc4f2b611d8c20a390fa03984eddc907f3ad8ce5b58d8a721" +version = "2.19.3" +source = "git+https://github.com/starkware-libs/cairo?branch=ron%2Fdeploy-v2%2Fcompiler#636de0fc36d81b580b8518afd1dcc76582d12507" dependencies = [ "cairo-lang-utils", "good_lp", @@ -669,14 +664,13 @@ dependencies = [ [[package]] name = "cairo-lang-filesystem" -version = "2.19.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf3d1e89da58481852b273a455986a035abd7127452f8275fe2bc022783b7f89" +version = "2.19.3" +source = "git+https://github.com/starkware-libs/cairo?branch=ron%2Fdeploy-v2%2Fcompiler#636de0fc36d81b580b8518afd1dcc76582d12507" dependencies = [ "cairo-lang-debug", "cairo-lang-proc-macros", "cairo-lang-utils", - "itertools 0.14.0", + "itertools 0.15.0", "path-clean", "salsa", "semver", @@ -687,9 +681,8 @@ dependencies = [ [[package]] name = "cairo-lang-formatter" -version = "2.19.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a80dc0ba2632faf759a25ecda755aaf0cb4324fce392b1feb652e259135081c6" +version = "2.19.3" +source = "git+https://github.com/starkware-libs/cairo?branch=ron%2Fdeploy-v2%2Fcompiler#636de0fc36d81b580b8518afd1dcc76582d12507" dependencies = [ "anyhow", "cairo-lang-diagnostics", @@ -699,7 +692,7 @@ dependencies = [ "cairo-lang-utils", "diffy", "ignore", - "itertools 0.14.0", + "itertools 0.15.0", "salsa", "serde", "thiserror", @@ -707,9 +700,8 @@ dependencies = [ [[package]] name = "cairo-lang-lowering" -version = "2.19.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "422cef0633dcd65a7b7d48a6e8a582830da289441df5bb566d38a7b74e1c51fa" +version = "2.19.3" +source = "git+https://github.com/starkware-libs/cairo?branch=ron%2Fdeploy-v2%2Fcompiler#636de0fc36d81b580b8518afd1dcc76582d12507" dependencies = [ "assert_matches", "cairo-lang-debug", @@ -722,12 +714,11 @@ dependencies = [ "cairo-lang-utils", "id-arena", "indent", - "itertools 0.14.0", + "itertools 0.15.0", "log", "num-bigint", "num-integer", "num-traits", - "postcard", "salsa", "serde", "starknet-types-core", @@ -737,9 +728,8 @@ dependencies = [ [[package]] name = "cairo-lang-parser" -version = "2.19.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e89b7b250bf93661f3c57b09428b0feb7e47f69e04636f860b24938e5a9a7c" +version = "2.19.3" +source = "git+https://github.com/starkware-libs/cairo?branch=ron%2Fdeploy-v2%2Fcompiler#636de0fc36d81b580b8518afd1dcc76582d12507" dependencies = [ "cairo-lang-diagnostics", "cairo-lang-filesystem", @@ -748,7 +738,7 @@ dependencies = [ "cairo-lang-syntax-codegen", "cairo-lang-utils", "colored 3.1.1", - "itertools 0.14.0", + "itertools 0.15.0", "num-bigint", "num-traits", "salsa", @@ -757,9 +747,8 @@ dependencies = [ [[package]] name = "cairo-lang-plugins" -version = "2.19.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4354cb3fe34bf0e1eebcbe3fff5953dcc5389f991caf7cd959086250b54ab55f" +version = "2.19.3" +source = "git+https://github.com/starkware-libs/cairo?branch=ron%2Fdeploy-v2%2Fcompiler#636de0fc36d81b580b8518afd1dcc76582d12507" dependencies = [ "cairo-lang-defs", "cairo-lang-diagnostics", @@ -769,7 +758,7 @@ dependencies = [ "cairo-lang-utils", "indent", "indoc", - "itertools 0.14.0", + "itertools 0.15.0", "salsa", ] @@ -781,9 +770,8 @@ checksum = "123ac0ecadf31bacae77436d72b88fa9caef2b8e92c89ce63a125ae911a12fae" [[package]] name = "cairo-lang-proc-macros" -version = "2.19.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c692bbc37b074f9e1c3f7fdcb5bddfa0c31768e0c052fbad882adf2c039aa1" +version = "2.19.3" +source = "git+https://github.com/starkware-libs/cairo?branch=ron%2Fdeploy-v2%2Fcompiler#636de0fc36d81b580b8518afd1dcc76582d12507" dependencies = [ "cairo-lang-debug", "proc-macro2", @@ -794,9 +782,8 @@ dependencies = [ [[package]] name = "cairo-lang-project" -version = "2.19.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "006338f1186ecd5da3b52b4bb86fd4c69f9f2a0f32b5d1055efa0c28c160a004" +version = "2.19.3" +source = "git+https://github.com/starkware-libs/cairo?branch=ron%2Fdeploy-v2%2Fcompiler#636de0fc36d81b580b8518afd1dcc76582d12507" dependencies = [ "cairo-lang-filesystem", "cairo-lang-utils", @@ -807,9 +794,8 @@ dependencies = [ [[package]] name = "cairo-lang-runnable-utils" -version = "2.19.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5003a11d12e7b299960ab94d7f1da03bfb8f85c2d4858ee5f2d88f0d007676f6" +version = "2.19.3" +source = "git+https://github.com/starkware-libs/cairo?branch=ron%2Fdeploy-v2%2Fcompiler#636de0fc36d81b580b8518afd1dcc76582d12507" dependencies = [ "cairo-lang-casm", "cairo-lang-sierra", @@ -824,9 +810,8 @@ dependencies = [ [[package]] name = "cairo-lang-runner" -version = "2.19.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf6a5b109faa35f59a1ef1c2fc04cd0c9086778f41857cec8e0bcd7dc513517f" +version = "2.19.3" +source = "git+https://github.com/starkware-libs/cairo?branch=ron%2Fdeploy-v2%2Fcompiler#636de0fc36d81b580b8518afd1dcc76582d12507" dependencies = [ "ark-ff 0.6.0", "ark-secp256k1 0.6.0", @@ -841,7 +826,7 @@ dependencies = [ "cairo-lang-utils", "cairo-vm", "clap", - "itertools 0.14.0", + "itertools 0.15.0", "keccak 0.2.0", "num-bigint", "num-integer", @@ -856,9 +841,8 @@ dependencies = [ [[package]] name = "cairo-lang-semantic" -version = "2.19.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a2fb4eed7bfc001f7fe028927bb4abeafa513764472e0f8b80cfd6ec19e07d" +version = "2.19.3" +source = "git+https://github.com/starkware-libs/cairo?branch=ron%2Fdeploy-v2%2Fcompiler#636de0fc36d81b580b8518afd1dcc76582d12507" dependencies = [ "cairo-lang-debug", "cairo-lang-defs", @@ -872,10 +856,10 @@ dependencies = [ "cairo-lang-utils", "id-arena", "indoc", - "itertools 0.14.0", + "itertools 0.15.0", "num-bigint", + "num-integer", "num-traits", - "postcard", "salsa", "serde", "sha3 0.12.0", @@ -886,16 +870,15 @@ dependencies = [ [[package]] name = "cairo-lang-sierra" -version = "2.19.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c07bb85ab735c71630540736044bc5f771b1a336dd0636a1f4708186746f40e" +version = "2.19.3" +source = "git+https://github.com/starkware-libs/cairo?branch=ron%2Fdeploy-v2%2Fcompiler#636de0fc36d81b580b8518afd1dcc76582d12507" dependencies = [ "anyhow", "cairo-lang-utils", "const-fnv1a-hash", "convert_case 0.11.0", "derivative", - "itertools 0.14.0", + "itertools 0.15.0", "lalrpop", "lalrpop-util", "num-bigint", @@ -912,15 +895,14 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-ap-change" -version = "2.19.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c291f44590a7c8e7e00b5b8adfa5ff7d4afab9e9b8cbd427c5757035e19b45" +version = "2.19.3" +source = "git+https://github.com/starkware-libs/cairo?branch=ron%2Fdeploy-v2%2Fcompiler#636de0fc36d81b580b8518afd1dcc76582d12507" dependencies = [ "cairo-lang-eq-solver", "cairo-lang-sierra", "cairo-lang-sierra-type-size", "cairo-lang-utils", - "itertools 0.14.0", + "itertools 0.15.0", "num-bigint", "num-traits", "thiserror", @@ -928,15 +910,14 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-gas" -version = "2.19.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c967cbee6e5e5a5c69fba183bb85e8906dba79cf12673c79b535e89b99fbd683" +version = "2.19.3" +source = "git+https://github.com/starkware-libs/cairo?branch=ron%2Fdeploy-v2%2Fcompiler#636de0fc36d81b580b8518afd1dcc76582d12507" dependencies = [ "cairo-lang-eq-solver", "cairo-lang-sierra", "cairo-lang-sierra-type-size", "cairo-lang-utils", - "itertools 0.14.0", + "itertools 0.15.0", "num-bigint", "num-traits", "thiserror", @@ -944,9 +925,8 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-generator" -version = "2.19.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8081833a3e5b483b7faff351b9606fb2d486be55c8fff467efaf383c193b0890" +version = "2.19.3" +source = "git+https://github.com/starkware-libs/cairo?branch=ron%2Fdeploy-v2%2Fcompiler#636de0fc36d81b580b8518afd1dcc76582d12507" dependencies = [ "cairo-lang-debug", "cairo-lang-defs", @@ -958,7 +938,7 @@ dependencies = [ "cairo-lang-sierra", "cairo-lang-syntax", "cairo-lang-utils", - "itertools 0.14.0", + "itertools 0.15.0", "num-traits", "rayon", "salsa", @@ -969,9 +949,8 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-to-casm" -version = "2.19.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b09e28e8a8a702516a898e48a933cf3136b92019c4bd3ccae00707e883b9367" +version = "2.19.3" +source = "git+https://github.com/starkware-libs/cairo?branch=ron%2Fdeploy-v2%2Fcompiler#636de0fc36d81b580b8518afd1dcc76582d12507" dependencies = [ "assert_matches", "cairo-lang-casm", @@ -981,7 +960,7 @@ dependencies = [ "cairo-lang-sierra-type-size", "cairo-lang-utils", "indoc", - "itertools 0.14.0", + "itertools 0.15.0", "num-bigint", "num-traits", "starknet-types-core", @@ -990,9 +969,8 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-type-size" -version = "2.19.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9c2b692133e92cf42ffc493fd8f6957a3a35b75b908fc53f287edb35f06aac9" +version = "2.19.3" +source = "git+https://github.com/starkware-libs/cairo?branch=ron%2Fdeploy-v2%2Fcompiler#636de0fc36d81b580b8518afd1dcc76582d12507" dependencies = [ "cairo-lang-sierra", "cairo-lang-utils", @@ -1000,9 +978,8 @@ dependencies = [ [[package]] name = "cairo-lang-starknet" -version = "2.19.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c27166eada9c2c812a2ff4db8f20ca4d6fead8a63390c02b93ea7f27da205120" +version = "2.19.3" +source = "git+https://github.com/starkware-libs/cairo?branch=ron%2Fdeploy-v2%2Fcompiler#636de0fc36d81b580b8518afd1dcc76582d12507" dependencies = [ "anyhow", "cairo-lang-compiler", @@ -1021,7 +998,7 @@ dependencies = [ "const_format", "indent", "indoc", - "itertools 0.14.0", + "itertools 0.15.0", "rayon", "salsa", "serde", @@ -1033,9 +1010,8 @@ dependencies = [ [[package]] name = "cairo-lang-starknet-classes" -version = "2.19.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10faa91e4be6065bd08f2da8d923721e25615ca94f50fd870faf5e52691b55b3" +version = "2.19.3" +source = "git+https://github.com/starkware-libs/cairo?branch=ron%2Fdeploy-v2%2Fcompiler#636de0fc36d81b580b8518afd1dcc76582d12507" dependencies = [ "cairo-lang-casm", "cairo-lang-sierra", @@ -1043,7 +1019,7 @@ dependencies = [ "cairo-lang-sierra-type-size", "cairo-lang-utils", "convert_case 0.11.0", - "itertools 0.14.0", + "itertools 0.15.0", "num-bigint", "num-integer", "num-traits", @@ -1057,16 +1033,15 @@ dependencies = [ [[package]] name = "cairo-lang-syntax" -version = "2.19.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0a90a23f458132951b20c267e2410d4eaf307e214bbcb5dabfd7ae0739b903" +version = "2.19.3" +source = "git+https://github.com/starkware-libs/cairo?branch=ron%2Fdeploy-v2%2Fcompiler#636de0fc36d81b580b8518afd1dcc76582d12507" dependencies = [ "cairo-lang-debug", "cairo-lang-filesystem", "cairo-lang-primitive-token", "cairo-lang-proc-macros", "cairo-lang-utils", - "itertools 0.14.0", + "itertools 0.15.0", "num-bigint", "num-traits", "salsa", @@ -1076,9 +1051,8 @@ dependencies = [ [[package]] name = "cairo-lang-syntax-codegen" -version = "2.19.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d63421b7a7204b8c57f15d488a09520959cd6e6fef48dbbd3a37071577873d15" +version = "2.19.3" +source = "git+https://github.com/starkware-libs/cairo?branch=ron%2Fdeploy-v2%2Fcompiler#636de0fc36d81b580b8518afd1dcc76582d12507" dependencies = [ "genco", "xshell", @@ -1086,9 +1060,8 @@ dependencies = [ [[package]] name = "cairo-lang-test-plugin" -version = "2.19.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaceca861261038c5162af5da78152dea4cc59a1197c32c742bee98e8d41b574" +version = "2.19.3" +source = "git+https://github.com/starkware-libs/cairo?branch=ron%2Fdeploy-v2%2Fcompiler#636de0fc36d81b580b8518afd1dcc76582d12507" dependencies = [ "anyhow", "cairo-lang-compiler", @@ -1105,7 +1078,7 @@ dependencies = [ "cairo-lang-syntax", "cairo-lang-utils", "indoc", - "itertools 0.14.0", + "itertools 0.15.0", "num-bigint", "num-traits", "salsa", @@ -1115,9 +1088,8 @@ dependencies = [ [[package]] name = "cairo-lang-test-runner" -version = "2.19.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0adb95e7b34619cbea9268b7014b8b36af1f8811c5bf1b2372a11c0ca07089" +version = "2.19.3" +source = "git+https://github.com/starkware-libs/cairo?branch=ron%2Fdeploy-v2%2Fcompiler#636de0fc36d81b580b8518afd1dcc76582d12507" dependencies = [ "anyhow", "cairo-lang-compiler", @@ -1130,7 +1102,7 @@ dependencies = [ "cairo-lang-test-plugin", "cairo-lang-utils", "colored 3.1.1", - "itertools 0.14.0", + "itertools 0.15.0", "num-traits", "rayon", "salsa", @@ -1139,9 +1111,8 @@ dependencies = [ [[package]] name = "cairo-lang-test-utils" -version = "2.19.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6e37ea508d269cfa17331db6395f445ca3a5c9cbf8565990edcb2a17d9d466" +version = "2.19.3" +source = "git+https://github.com/starkware-libs/cairo?branch=ron%2Fdeploy-v2%2Fcompiler#636de0fc36d81b580b8518afd1dcc76582d12507" dependencies = [ "cairo-lang-formatter", "cairo-lang-proc-macros", @@ -1153,13 +1124,12 @@ dependencies = [ [[package]] name = "cairo-lang-utils" -version = "2.19.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a994da2cbd8f7be81e9951d20b1f98e220e03c61e18e6cbde0bb4cc911b90c8d" +version = "2.19.3" +source = "git+https://github.com/starkware-libs/cairo?branch=ron%2Fdeploy-v2%2Fcompiler#636de0fc36d81b580b8518afd1dcc76582d12507" dependencies = [ "hashbrown 0.17.1", "indexmap", - "itertools 0.14.0", + "itertools 0.15.0", "num-bigint", "num-traits", "salsa", @@ -2291,11 +2261,11 @@ dependencies = [ [[package]] name = "hashlink" -version = "0.10.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" +checksum = "32069d97bb81e38fa67eab65e3393bf804bb85969f2bc06bf13f64aef5aba248" dependencies = [ - "hashbrown 0.15.5", + "hashbrown 0.17.1", ] [[package]] @@ -2451,9 +2421,9 @@ dependencies = [ [[package]] name = "intrusive-collections" -version = "0.9.7" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "189d0897e4cbe8c75efedf3502c18c887b05046e59d28404d4d8e46cbc4d1e86" +checksum = "4b719c59241cfaac1042a6d26787e28ed7ee4a4e21a5a907786f54222d1b0062" dependencies = [ "memoffset", ] @@ -2511,6 +2481,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b4baf93f58d4425749ca49a51c50ebab072c5df6994d08fed93541c331481dc" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.18" @@ -3562,9 +3541,9 @@ dependencies = [ [[package]] name = "salsa" -version = "0.26.2" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4612ff789805e65c87e9b38cb749a293212a615af065bed8a2001086801498c3" +checksum = "ffbaab832e2ea754afda4a738f987dd1e8bd30c9e5d8c981ee6a3934386095e2" dependencies = [ "boxcar", "crossbeam-queue", @@ -3588,15 +3567,15 @@ dependencies = [ [[package]] name = "salsa-macro-rules" -version = "0.26.2" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58e354cbac6939b9b09cd9c11fb419a53e64b4a0f755d929f56a09f4cc752e41" +checksum = "de6872462ac73d39969a836273c24163e6a26a4e08f5114fcd80e25af30ea9c6" [[package]] name = "salsa-macros" -version = "0.26.2" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3067861075c2b80608f84ad49fb88f2c7610b94cdf8b4201e79ddee87f8980c8" +checksum = "76bc78ffaf65b1a9175818592c5130aa10b1bb245a905722fd4db87cea8a8457" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index f0ee0a9fb7..bcde5df20d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,24 +34,27 @@ ark-secp256k1 = "0.5.0" ark-secp256r1 = "0.5.0" bincode = "2.0.1" bumpalo = "3.16.0" -cairo-lang-casm = "~2.19.0-rc.3" -cairo-lang-compiler = "~2.19.0-rc.3" -cairo-lang-defs = "~2.19.0-rc.3" -cairo-lang-filesystem = "~2.19.0-rc.3" -cairo-lang-lowering = "~2.19.0-rc.3" -cairo-lang-runner = "~2.19.0-rc.3" -cairo-lang-semantic = "~2.19.0-rc.3" -cairo-lang-sierra = "~2.19.0-rc.3" -cairo-lang-sierra-ap-change = "~2.19.0-rc.3" -cairo-lang-sierra-gas = "~2.19.0-rc.3" -cairo-lang-sierra-generator = "~2.19.0-rc.3" -cairo-lang-sierra-to-casm = "~2.19.0-rc.3" -cairo-lang-sierra-type-size = "~2.19.0-rc.3" -cairo-lang-starknet = "~2.19.0-rc.3" -cairo-lang-starknet-classes = "~2.19.0-rc.3" -cairo-lang-test-plugin = "~2.19.0-rc.3" -cairo-lang-test-runner = "~2.19.0-rc.3" -cairo-lang-utils = "~2.19.0-rc.3" +# NOTE(deploy_v2): bumped from "~2.19.0-rc.3" to the release carrying the `DeployV2` Sierra libfunc +# variant. That release is not yet published, so the `[patch.crates-io]` block at the bottom of this +# file redirects these to the local cairo checkout during development (see the note there). +cairo-lang-casm = "2.19.3" +cairo-lang-compiler = "2.19.3" +cairo-lang-defs = "2.19.3" +cairo-lang-filesystem = "2.19.3" +cairo-lang-lowering = "2.19.3" +cairo-lang-runner = "2.19.3" +cairo-lang-semantic = "2.19.3" +cairo-lang-sierra = "2.19.3" +cairo-lang-sierra-ap-change = "2.19.3" +cairo-lang-sierra-gas = "2.19.3" +cairo-lang-sierra-generator = "2.19.3" +cairo-lang-sierra-to-casm = "2.19.3" +cairo-lang-sierra-type-size = "2.19.3" +cairo-lang-starknet = "2.19.3" +cairo-lang-starknet-classes = "2.19.3" +cairo-lang-test-plugin = "2.19.3" +cairo-lang-test-runner = "2.19.3" +cairo-lang-utils = "2.19.3" cairo-native-bin-utils.path = "binaries/cairo-native-bin-utils" cairo-native = { path = ".", version = "0.9.0-rc.7" } cairo-starknet-syscalls = { path = "cairo-starknet-syscalls", version = "0.9.0-rc.7" } @@ -249,3 +252,28 @@ required-features = [ "testing" ] [[example]] name = "easy_api" required-features = [ "testing" ] + +# --- TEMPORARY dev override (deploy_v2) --- +# The `deploy_v2` syscall needs the `DeployV2` Sierra libfunc variant, which is not yet in a +# published cairo-lang-* release. Until one is, build against the cairo `deploy_v2` compiler branch +# (https://github.com/starkware-libs/cairo/pull/10214). Remove this block once a release carries the +# variant — the version pins above already target it. +[patch.crates-io] +cairo-lang-casm = { git = "https://github.com/starkware-libs/cairo", branch = "ron/deploy-v2/compiler" } +cairo-lang-compiler = { git = "https://github.com/starkware-libs/cairo", branch = "ron/deploy-v2/compiler" } +cairo-lang-defs = { git = "https://github.com/starkware-libs/cairo", branch = "ron/deploy-v2/compiler" } +cairo-lang-filesystem = { git = "https://github.com/starkware-libs/cairo", branch = "ron/deploy-v2/compiler" } +cairo-lang-lowering = { git = "https://github.com/starkware-libs/cairo", branch = "ron/deploy-v2/compiler" } +cairo-lang-runner = { git = "https://github.com/starkware-libs/cairo", branch = "ron/deploy-v2/compiler" } +cairo-lang-semantic = { git = "https://github.com/starkware-libs/cairo", branch = "ron/deploy-v2/compiler" } +cairo-lang-sierra = { git = "https://github.com/starkware-libs/cairo", branch = "ron/deploy-v2/compiler" } +cairo-lang-sierra-ap-change = { git = "https://github.com/starkware-libs/cairo", branch = "ron/deploy-v2/compiler" } +cairo-lang-sierra-gas = { git = "https://github.com/starkware-libs/cairo", branch = "ron/deploy-v2/compiler" } +cairo-lang-sierra-generator = { git = "https://github.com/starkware-libs/cairo", branch = "ron/deploy-v2/compiler" } +cairo-lang-sierra-to-casm = { git = "https://github.com/starkware-libs/cairo", branch = "ron/deploy-v2/compiler" } +cairo-lang-sierra-type-size = { git = "https://github.com/starkware-libs/cairo", branch = "ron/deploy-v2/compiler" } +cairo-lang-starknet = { git = "https://github.com/starkware-libs/cairo", branch = "ron/deploy-v2/compiler" } +cairo-lang-starknet-classes = { git = "https://github.com/starkware-libs/cairo", branch = "ron/deploy-v2/compiler" } +cairo-lang-test-plugin = { git = "https://github.com/starkware-libs/cairo", branch = "ron/deploy-v2/compiler" } +cairo-lang-test-runner = { git = "https://github.com/starkware-libs/cairo", branch = "ron/deploy-v2/compiler" } +cairo-lang-utils = { git = "https://github.com/starkware-libs/cairo", branch = "ron/deploy-v2/compiler" } diff --git a/cairo-starknet-syscalls/src/lib.rs b/cairo-starknet-syscalls/src/lib.rs index 04b1694c15..d577b1123f 100644 --- a/cairo-starknet-syscalls/src/lib.rs +++ b/cairo-starknet-syscalls/src/lib.rs @@ -235,6 +235,17 @@ pub trait StarknetSyscallHandler { remaining_gas: &mut u64, ) -> SyscallResult<(Felt, Vec)>; + /// Deploys a contract, deriving its address with the Blake-escaped derivation instead of + /// Pedersen (the `deploy_v2` syscall). Same request/response as [`Self::deploy`]. + fn deploy_v2( + &mut self, + class_hash: Felt, + contract_address_salt: Felt, + calldata: &[Felt], + deploy_from_zero: bool, + remaining_gas: &mut u64, + ) -> SyscallResult<(Felt, Vec)>; + fn replace_class(&mut self, class_hash: Felt, remaining_gas: &mut u64) -> SyscallResult<()>; fn library_call( diff --git a/debug_utils/sierra-emu/programs/syscalls.cairo b/debug_utils/sierra-emu/programs/syscalls.cairo index e8e23cbcfe..a8b9e647de 100644 --- a/debug_utils/sierra-emu/programs/syscalls.cairo +++ b/debug_utils/sierra-emu/programs/syscalls.cairo @@ -1,7 +1,7 @@ use starknet::ClassHash; use starknet::{ call_contract_syscall, ContractAddress, - deploy_syscall, emit_event_syscall, ExecutionInfo, get_block_hash_syscall, + deploy_syscall, deploy_v2_syscall, emit_event_syscall, ExecutionInfo, get_block_hash_syscall, keccak_syscall, library_call_syscall, replace_class_syscall, send_message_to_l1_syscall, storage_address_try_from_felt252, storage_read_syscall, storage_write_syscall, SyscallResult, @@ -29,6 +29,10 @@ fn deploy() -> SyscallResult<(ContractAddress, Span)> { deploy_syscall(ZERO_CLASS_HASH, 0, array![].span(), false) } +fn deploy_v2() -> SyscallResult<(ContractAddress, Span)> { + deploy_v2_syscall(ZERO_CLASS_HASH, 0, array![].span(), false) +} + fn replace_class() -> SyscallResult<()> { replace_class_syscall(ZERO_CLASS_HASH) } diff --git a/debug_utils/sierra-emu/src/debug.rs b/debug_utils/sierra-emu/src/debug.rs index 1c2e7efcfd..da921763fc 100644 --- a/debug_utils/sierra-emu/src/debug.rs +++ b/debug_utils/sierra-emu/src/debug.rs @@ -354,6 +354,7 @@ pub fn libfunc_to_name(value: &CoreConcreteLibfunc) -> &'static str { StarknetConcreteLibfunc::GetExecutionInfo(_) => "get_exec_info_v1", StarknetConcreteLibfunc::GetExecutionInfoV2(_) => "get_exec_info_v2", StarknetConcreteLibfunc::Deploy(_) => "deploy", + StarknetConcreteLibfunc::DeployV2(_) => "deploy_v2", StarknetConcreteLibfunc::Keccak(_) => "keccak", StarknetConcreteLibfunc::LibraryCall(_) => "library_call", StarknetConcreteLibfunc::ReplaceClass(_) => "replace_class", diff --git a/debug_utils/sierra-emu/src/starknet.rs b/debug_utils/sierra-emu/src/starknet.rs index be6f41da49..15db21e02a 100644 --- a/debug_utils/sierra-emu/src/starknet.rs +++ b/debug_utils/sierra-emu/src/starknet.rs @@ -159,6 +159,18 @@ impl StarknetSyscallHandler for StubSyscallHandler { unimplemented!() } + fn deploy_v2( + &mut self, + _class_hash: Felt, + _contract_address_salt: Felt, + _calldata: &[Felt], + _deploy_from_zero: bool, + _remaining_gas: &mut u64, + ) -> SyscallResult<(Felt, Vec)> { + // Deployment requires constructor execution, which the stub doesn't model. + unimplemented!() + } + fn replace_class(&mut self, _class_hash: Felt, _remaining_gas: &mut u64) -> SyscallResult<()> { // Class replacement updates a registry the stub doesn't track. unimplemented!() diff --git a/debug_utils/sierra-emu/src/vm/starknet.rs b/debug_utils/sierra-emu/src/vm/starknet.rs index 8c9a883490..60a3b76cfc 100644 --- a/debug_utils/sierra-emu/src/vm/starknet.rs +++ b/debug_utils/sierra-emu/src/vm/starknet.rs @@ -94,6 +94,9 @@ pub fn eval( eval_get_execution_info_v2(registry, info, args, syscall_handler) } StarknetConcreteLibfunc::Deploy(info) => eval_deploy(registry, info, args, syscall_handler), + StarknetConcreteLibfunc::DeployV2(info) => { + eval_deploy_v2(registry, info, args, syscall_handler) + } StarknetConcreteLibfunc::Keccak(info) => eval_keccak(registry, info, args, syscall_handler), StarknetConcreteLibfunc::Sha256ProcessBlock(info) => { eval_sha256_process_block(registry, info, args, syscall_handler) @@ -1094,6 +1097,90 @@ fn eval_deploy( } } +/// Same request/response layout as [`eval_deploy`], but dispatches to the handler's `deploy_v2` +/// method (Blake-escaped address derivation). +fn eval_deploy_v2( + registry: &ProgramRegistry, + info: &SignatureOnlyConcreteLibfunc, + args: Vec, + syscall_handler: &mut impl StarknetSyscallHandler, +) -> EvalAction { + let [Value::U64(mut gas), system, Value::Felt(class_hash), Value::Felt(contract_address_salt), Value::Struct(calldata), Value::Enum { + self_ty: _, + index: deploy_from_zero, + payload: _, + }]: [Value; 6] = args.try_into().unwrap() + else { + panic!() + }; + + let deploy_from_zero = deploy_from_zero != 0; + + let [Value::Array { + ty: _, + data: calldata, + }]: [Value; 1] = calldata.try_into().unwrap() + else { + panic!() + }; + + let calldata = calldata + .into_iter() + .map(|x| match x { + Value::Felt(x) => x, + _ => unreachable!(), + }) + .collect::>(); + + // get felt type from the error branch array + let felt_ty = { + match registry + .get_type(&info.branch_signatures()[1].vars[2].ty) + .unwrap() + { + CoreTypeConcrete::Array(info) => info.ty.clone(), + _ => unreachable!(), + } + }; + + let result = syscall_handler.deploy_v2( + class_hash, + contract_address_salt, + &calldata, + deploy_from_zero, + &mut gas, + ); + + match result { + Ok((contract_address, return_values)) => EvalAction::NormalBranch( + 0, + smallvec![ + Value::U64(gas), + system, + Value::Felt(contract_address), + Value::Struct(vec![Value::Array { + ty: felt_ty, + data: return_values + .into_iter() + .map(Value::Felt) + .collect::>(), + }]) + ], + ), + Err(e) => EvalAction::NormalBranch( + 1, + smallvec![ + Value::U64(gas), + system, + Value::Array { + ty: felt_ty, + data: e.into_iter().map(Value::Felt).collect::>(), + } + ], + ), + } +} + fn eval_keccak( registry: &ProgramRegistry, info: &SignatureOnlyConcreteLibfunc, diff --git a/examples/erc20.rs b/examples/erc20.rs index b23c4fbfd1..550a0b5a1f 100644 --- a/examples/erc20.rs +++ b/examples/erc20.rs @@ -108,6 +108,21 @@ impl StarknetSyscallHandler for SyscallHandler { )) } + fn deploy_v2( + &mut self, + class_hash: Felt, + contract_address_salt: Felt, + calldata: &[Felt], + deploy_from_zero: bool, + _gas: &mut u64, + ) -> SyscallResult<(Felt, Vec)> { + println!("Called `deploy_v2({class_hash}, {contract_address_salt}, {calldata:?}, {deploy_from_zero})` from MLIR."); + Ok(( + class_hash + contract_address_salt, + calldata.iter().map(|x| x + Felt::ONE).collect(), + )) + } + fn replace_class(&mut self, class_hash: Felt, _gas: &mut u64) -> SyscallResult<()> { println!("Called `replace_class({class_hash})` from MLIR."); Ok(()) diff --git a/examples/starknet.rs b/examples/starknet.rs index 4d06dc6900..64ef0901b0 100644 --- a/examples/starknet.rs +++ b/examples/starknet.rs @@ -150,6 +150,21 @@ impl StarknetSyscallHandler for SyscallHandler { )) } + fn deploy_v2( + &mut self, + class_hash: Felt, + contract_address_salt: Felt, + calldata: &[Felt], + deploy_from_zero: bool, + _gas: &mut u64, + ) -> SyscallResult<(Felt, Vec)> { + println!("Called `deploy_v2({class_hash}, {contract_address_salt}, {calldata:?}, {deploy_from_zero})` from MLIR."); + Ok(( + class_hash + contract_address_salt, + calldata.iter().map(|x| x + Felt::ONE).collect(), + )) + } + fn replace_class(&mut self, class_hash: Felt, _gas: &mut u64) -> SyscallResult<()> { println!("Called `replace_class({class_hash})` from MLIR."); Ok(()) diff --git a/src/debug.rs b/src/debug.rs index f68fcde3be..ec2a1eb4f8 100644 --- a/src/debug.rs +++ b/src/debug.rs @@ -354,6 +354,7 @@ pub const fn libfunc_to_name(value: &CoreConcreteLibfunc) -> &'static str { StarknetConcreteLibfunc::GetExecutionInfoV2(_) => "get_exec_info_v2", StarknetConcreteLibfunc::GetExecutionInfoV3(_) => "get_exec_info_v3", StarknetConcreteLibfunc::Deploy(_) => "deploy", + StarknetConcreteLibfunc::DeployV2(_) => "deploy_v2", StarknetConcreteLibfunc::Keccak(_) => "keccak", StarknetConcreteLibfunc::LibraryCall(_) => "library_call", StarknetConcreteLibfunc::ReplaceClass(_) => "replace_class", diff --git a/src/libfuncs/starknet.rs b/src/libfuncs/starknet.rs index d3b9c477f9..1daa8356bd 100644 --- a/src/libfuncs/starknet.rs +++ b/src/libfuncs/starknet.rs @@ -127,6 +127,9 @@ pub fn build<'ctx, 'this>( StarknetConcreteLibfunc::Deploy(info) => { build_deploy(context, registry, entry, location, helper, metadata, info) } + StarknetConcreteLibfunc::DeployV2(info) => { + build_deploy_v2(context, registry, entry, location, helper, metadata, info) + } StarknetConcreteLibfunc::Keccak(info) => { build_keccak(context, registry, entry, location, helper, metadata, info) } @@ -1177,6 +1180,54 @@ pub fn build_deploy<'ctx, 'this>( helper: &LibfuncHelper<'ctx, 'this>, metadata: &mut MetadataStorage, info: &SignatureOnlyConcreteLibfunc, +) -> Result<()> { + build_deploy_impl( + context, + registry, + entry, + location, + helper, + metadata, + info, + StarknetSyscallHandlerCallbacks::<()>::DEPLOY, + ) +} + +/// Same request/response layout as [`build_deploy`], but dispatches to the handler's `deploy_v2` +/// method (Blake-escaped address derivation) via its vtable offset. +pub fn build_deploy_v2<'ctx, 'this>( + context: &'ctx Context, + registry: &ProgramRegistry, + entry: &'this Block<'ctx>, + location: Location<'ctx>, + helper: &LibfuncHelper<'ctx, 'this>, + metadata: &mut MetadataStorage, + info: &SignatureOnlyConcreteLibfunc, +) -> Result<()> { + build_deploy_impl( + context, + registry, + entry, + location, + helper, + metadata, + info, + StarknetSyscallHandlerCallbacks::<()>::DEPLOY_V2, + ) +} + +/// Shared body of [`build_deploy`] and [`build_deploy_v2`]; `callback_offset` selects which handler +/// vtable entry (`DEPLOY` or `DEPLOY_V2`) the syscall dispatches to. +#[allow(clippy::too_many_arguments)] +fn build_deploy_impl<'ctx, 'this>( + context: &'ctx Context, + registry: &ProgramRegistry, + entry: &'this Block<'ctx>, + location: Location<'ctx>, + helper: &LibfuncHelper<'ctx, 'this>, + metadata: &mut MetadataStorage, + info: &SignatureOnlyConcreteLibfunc, + callback_offset: usize, ) -> Result<()> { // Extract self pointer. let ptr = entry.load( @@ -1314,9 +1365,7 @@ pub fn build_deploy<'ctx, 'this>( context, location, entry.arg(1)?, - &[GepIndex::Const( - StarknetSyscallHandlerCallbacks::<()>::DEPLOY.try_into()?, - )], + &[GepIndex::Const(callback_offset.try_into()?)], pointer(context, 0), )?; let fn_ptr = entry.load(context, location, fn_ptr, llvm::r#type::pointer(context, 0))?; diff --git a/src/starknet.rs b/src/starknet.rs index 0a6051195f..93a83055aa 100644 --- a/src/starknet.rs +++ b/src/starknet.rs @@ -94,6 +94,17 @@ impl StarknetSyscallHandler for DummySyscallHandler { unimplemented!() } + fn deploy_v2( + &mut self, + _class_hash: Felt, + _contract_address_salt: Felt, + _calldata: &[Felt], + _deploy_from_zero: bool, + _remaining_gas: &mut u64, + ) -> SyscallResult<(Felt, Vec)> { + unimplemented!() + } + fn replace_class(&mut self, _class_hash: Felt, _remaining_gas: &mut u64) -> SyscallResult<()> { unimplemented!() } @@ -456,6 +467,15 @@ pub(crate) mod handler { calldata: &ArrayAbi, deploy_from_zero: bool, ), + deploy_v2: extern "C" fn( + result_ptr: &mut SyscallResultAbi<(Felt252Abi, ArrayAbi)>, + ptr: &mut T, + gas: &mut u64, + class_hash: &Felt252Abi, + contract_address_salt: &Felt252Abi, + calldata: &ArrayAbi, + deploy_from_zero: bool, + ), replace_class: extern "C" fn( result_ptr: &mut SyscallResultAbi<()>, ptr: &mut T, @@ -631,6 +651,7 @@ pub(crate) mod handler { // Callback field indices. pub const CALL_CONTRACT: usize = field_offset!(Self, call_contract) >> 3; pub const DEPLOY: usize = field_offset!(Self, deploy) >> 3; + pub const DEPLOY_V2: usize = field_offset!(Self, deploy_v2) >> 3; pub const EMIT_EVENT: usize = field_offset!(Self, emit_event) >> 3; pub const GET_BLOCK_HASH: usize = field_offset!(Self, get_block_hash) >> 3; pub const GET_EXECUTION_INFO: usize = field_offset!(Self, get_execution_info) >> 3; @@ -677,6 +698,7 @@ pub(crate) mod handler { get_execution_info_v2: Self::wrap_get_execution_info_v2, get_execution_info_v3: Self::wrap_get_execution_info_v3, deploy: Self::wrap_deploy, + deploy_v2: Self::wrap_deploy_v2, replace_class: Self::wrap_replace_class, library_call: Self::wrap_library_call, call_contract: Self::wrap_call_contract, @@ -1067,6 +1089,43 @@ pub(crate) mod handler { }; } + extern "C" fn wrap_deploy_v2( + result_ptr: &mut SyscallResultAbi<(Felt252Abi, ArrayAbi)>, + ptr: &mut T, + gas: &mut u64, + class_hash: &Felt252Abi, + contract_address_salt: &Felt252Abi, + calldata: &ArrayAbi, + deploy_from_zero: bool, + ) { + let class_hash = Felt::from(class_hash); + let contract_address_salt = Felt::from(contract_address_salt); + + let calldata_vec: Vec<_> = calldata.into(); + + let result = ptr.deploy_v2( + class_hash, + contract_address_salt, + &calldata_vec, + deploy_from_zero, + gas, + ); + + *result_ptr = match result { + Ok(x) => { + let felts: Vec<_> = x.1.iter().map(|x| Felt252Abi(x.to_bytes_le())).collect(); + let felts_ptr = unsafe { Self::alloc_mlir_array(&felts) }; + SyscallResultAbi { + ok: ManuallyDrop::new(SyscallResultAbiOk { + tag: 0u8, + payload: ManuallyDrop::new((Felt252Abi(x.0.to_bytes_le()), felts_ptr)), + }), + } + } + Err(e) => Self::wrap_error(&e), + }; + } + extern "C" fn wrap_replace_class( result_ptr: &mut SyscallResultAbi<()>, ptr: &mut T, diff --git a/src/starknet_stub.rs b/src/starknet_stub.rs index 0009315244..d608c600c9 100644 --- a/src/starknet_stub.rs +++ b/src/starknet_stub.rs @@ -32,7 +32,7 @@ use num_traits::Zero; use sha2::digest::generic_array::GenericArray; use starknet_types_core::{ felt::{Felt, NonZeroFelt}, - hash::{Pedersen, StarkHash}, + hash::{Blake2Felt252, Pedersen, StarkHash}, }; use tracing::instrument; @@ -564,6 +564,68 @@ impl StarknetSyscallHandler for &mut StubSyscallHandler { } } + /// Identical to [`Self::deploy`] except the deployed address is derived with the Blake-escaped + /// derivation ([`calculate_contract_address_blake_escaped`]) instead of Pedersen. Must match + /// the sequencer's `starknet_api::core::calculate_contract_address` for the `Blake2` arm and + /// the cairo runner's `calculate_contract_address_blake_escaped`. + fn deploy_v2( + &mut self, + class_hash: Felt, + contract_address_salt: Felt, + calldata: &[Felt], + deploy_from_zero: bool, + remaining_gas: &mut u64, + ) -> crate::starknet::SyscallResult<(Felt, Vec)> { + tracing::debug!("called"); + deduct_gas(remaining_gas, gas_costs::DEPLOY_V2)?; + + let deployer_address = if deploy_from_zero { + Felt::zero() + } else { + self.execution_info.contract_address + }; + let deployed_contract_address = calculate_contract_address_blake_escaped( + contract_address_salt, + class_hash, + calldata, + deployer_address, + ); + + let Some(contract_info) = self.contracts_info.get(&class_hash) else { + return Err(vec![Felt::from_bytes_be_slice(b"CLASS_HASH_NOT_FOUND")]); + }; + + if self + .deployed_contracts + .insert(deployed_contract_address, class_hash) + .is_some() + { + return Err(vec![Felt::from_bytes_be_slice( + b"CONTRACT_ALREADY_DEPLOYED", + )]); + } + + if let Some(constructor) = contract_info.constructor.clone() { + let old_addrs = self.open_caller_context((deployed_contract_address, deployer_address)); + let res = self.call_entry_point(remaining_gas, &constructor, calldata); + self.close_caller_context(old_addrs); + match res { + Ok(res) => Ok((deployed_contract_address, res)), + Err(mut res) => { + res.push(Felt::from_bytes_be_slice(b"CONSTRUCTOR_FAILED")); + Err(res) + } + } + } else if calldata.is_empty() { + Ok((deployed_contract_address, vec![])) + } else { + // Remove the contract from the deployed contracts, + // since it failed to deploy. + self.deployed_contracts.remove(&deployed_contract_address); + Err(vec![Felt::from_bytes_be_slice(b"INVALID_CALLDATA_LEN")]) + } + } + #[instrument(skip(self))] fn replace_class( &mut self, @@ -1055,6 +1117,85 @@ pub fn deduct_gas(gas: &mut u64, price: u64) -> Result<(), Vec> { } } +/// Max value for a contract address: `2**251 - 256`. +const CONTRACT_ADDRESS_BOUND_FELT: Felt = + Felt::from_hex_unchecked("0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00"); +const CONTRACT_ADDRESS_BOUND: NonZeroFelt = + NonZeroFelt::from_felt_unchecked(CONTRACT_ADDRESS_BOUND_FELT); +/// Cairo string for "STARKNET_CONTRACT_ADDRESS". +const CONTRACT_ADDRESS_PREFIX: Felt = + Felt::from_hex_unchecked("0x535441524b4e45545f434f4e54524143545f41444452455353"); +/// The field prime minus [`CONTRACT_ADDRESS_BOUND_FELT`]. Addresses below this bound have a second +/// lift into the field: both `address` and `address + CONTRACT_ADDRESS_BOUND_FELT` are below `p`. +const SECOND_LIFT_BOUND: Felt = + Felt::from_hex_unchecked("0x11000000000000000000000000000000000000000000000101"); +/// The STARK curve is `y^2 = x^3 + ALPHA * x + BETA`. +const STARK_CURVE_ALPHA: Felt = Felt::ONE; +const STARK_CURVE_BETA: Felt = + Felt::from_hex_unchecked("0x6f21413efbe40de150e596d72f7a8c5609ad26c15c915c1f4cdfcb99cee9e89"); + +/// Calculates the address of a Starknet contract with the Blake-escaped derivation used by the +/// `deploy_v2` syscall (and `deploy_account` v4). +/// +/// The raw address is the BLAKE2s felt-array hash of the same preimage `deploy` hashes with +/// Pedersen, reduced modulo [`CONTRACT_ADDRESS_BOUND_FELT`]. It is then incremented (wrapping, +/// skipping the reserved `0x0`/`0x1`) until it is provably unreachable by any Pedersen derivation, +/// so the two schemes' address spaces are disjoint. Must match the sequencer's +/// `starknet_api::core::calculate_contract_address` for the `Blake2` arm. +fn calculate_contract_address_blake_escaped( + salt: Felt, + class_hash: Felt, + constructor_calldata: &[Felt], + deployer_address: Felt, +) -> Felt { + let constructor_calldata_hash = + Blake2Felt252::encode_felt252_data_and_calc_blake_hash(constructor_calldata); + let raw_address = Blake2Felt252::encode_felt252_data_and_calc_blake_hash(&[ + CONTRACT_ADDRESS_PREFIX, + deployer_address, + salt, + class_hash, + constructor_calldata_hash, + ]) + .mod_floor(&CONTRACT_ADDRESS_BOUND); + escape_pedersen_image(raw_address) +} + +/// Returns `value^3 + STARK_CURVE_ALPHA * value + STARK_CURVE_BETA` — a square in the field iff +/// `value` is the x-coordinate of a STARK curve point. +fn stark_curve_cubic(value: Felt) -> Felt { + value * value * value + STARK_CURVE_ALPHA * value + STARK_CURVE_BETA +} + +/// Returns whether `value` is the x-coordinate of a STARK curve point (`stark_curve_cubic(value)` +/// is a quadratic residue, i.e. `t == 0` or `legendre(t) == 1`). +fn is_stark_curve_x_coordinate(value: Felt) -> bool { + stark_curve_cubic(value).sqrt().is_some() +} + +/// Returns whether some Pedersen hash output reduces (mod [`CONTRACT_ADDRESS_BOUND_FELT`]) to +/// `address`. A Pedersen output is the x-coordinate of a STARK curve point, so `address` is +/// reachable iff one of its lifts into the field is a curve x-coordinate. +fn is_pedersen_reachable_address(address: Felt) -> bool { + is_stark_curve_x_coordinate(address) + || (address < SECOND_LIFT_BOUND + && is_stark_curve_x_coordinate(address + CONTRACT_ADDRESS_BOUND_FELT)) +} + +/// Increments `raw_address` (wrapping mod [`CONTRACT_ADDRESS_BOUND_FELT`], skipping the reserved +/// `0x0`/`0x1`) until no Pedersen derivation can reach it. Expected ~1 increment; each step costs +/// one residuosity check, never a re-hash. +fn escape_pedersen_image(raw_address: Felt) -> Felt { + let mut address = raw_address; + while address < Felt::TWO || is_pedersen_reachable_address(address) { + address += Felt::ONE; + if address == CONTRACT_ADDRESS_BOUND_FELT { + address = Felt::ZERO; + } + } + address +} + /// Gas costs for syscalls. /// /// Taken from cairo-lang-runner syscall handler implementation. @@ -1069,6 +1210,8 @@ mod gas_costs { // Gas cost for each syscall, minus the precharged base amount. pub const CALL_CONTRACT: u64 = 10 * STEP + ENTRY_POINT; pub const DEPLOY: u64 = 200 * STEP + ENTRY_POINT; + // Provisional: same profile as `DEPLOY` until a measured one lands (sequencer-side). + pub const DEPLOY_V2: u64 = 200 * STEP + ENTRY_POINT; pub const EMIT_EVENT: u64 = 10 * STEP; pub const GET_BLOCK_HASH: u64 = 50 * STEP; pub const GET_EXECUTION_INFO: u64 = 10 * STEP; @@ -1098,6 +1241,68 @@ mod gas_costs { mod tests { use super::*; + /// The five frozen Blake-escaped derivation vectors (0/1/2/3/7 escape steps), shared with the + /// sequencer and the cairo runner. `deploy_from_zero = true` (deployer = 0), + /// `class_hash = 0x4242`, `calldata = [42, 2 ** 63, 1337]`. + #[test] + fn test_calculate_contract_address_blake_escaped() { + let deployer_address = Felt::ZERO; + let class_hash = Felt::from(0x4242); + let calldata = [Felt::from(42), Felt::TWO.pow(63_u32), Felt::from(1337)]; + + for (salt, expected) in [ + ( + 777, + "0x781e95f4b806dfe5b550756620c77a108d974a5b5d1198b1d45901ac1f89e9f", + ), + ( + 771, + "0x566c3e328f3fd5a311267250cadc3c1c4de799db54180fcf862fe90b622571d", + ), + ( + 776, + "0x1cd7f5c31ef1b147b816048b025a6cc345e7e023aa8ed97222a883e31dc8435", + ), + ( + 775, + "0x4f7ba32369d7f68c42a7619242a52a5be9e803459f5afae1772d9377b161c4c", + ), + ( + 774, + "0x47d0c1ff356a1d540cd9f2efa122b60168b1007ef0603af0857bc6100e4b8e8", + ), + ] { + let salt = Felt::from(salt); + assert_eq!( + calculate_contract_address_blake_escaped( + salt, + class_hash, + &calldata, + deployer_address, + ), + Felt::from_hex(expected).unwrap(), + "wrong Blake-escaped address for salt {salt}", + ); + } + } + + /// The frozen `pedersen_reachable` truth table, shared with the sequencer and the cairo runner. + #[test] + fn test_is_pedersen_reachable_address() { + for (address, expected) in [ + (0x1_u64, true), + (0x2_u64, true), + (0x5_u64, false), + (0x1234567890abcdef_u64, true), + ] { + assert_eq!( + is_pedersen_reachable_address(Felt::from(address)), + expected, + "wrong pedersen_reachable for {address:#x}", + ); + } + } + #[test] fn test_secp256k1_get_xy() { let p = Secp256k1Point { diff --git a/test_data/programs/starknet/syscalls.cairo b/test_data/programs/starknet/syscalls.cairo index 58276344a4..a24bf7ab01 100644 --- a/test_data/programs/starknet/syscalls.cairo +++ b/test_data/programs/starknet/syscalls.cairo @@ -1,6 +1,6 @@ use starknet::{ call_contract_syscall, ContractAddress, - deploy_syscall, emit_event_syscall, ExecutionInfo, get_block_hash_syscall, + deploy_syscall, deploy_v2_syscall, emit_event_syscall, ExecutionInfo, get_block_hash_syscall, keccak_syscall, library_call_syscall, replace_class_syscall, send_message_to_l1_syscall, storage_address_try_from_felt252, storage_read_syscall, storage_write_syscall, SyscallResult, @@ -43,6 +43,10 @@ fn deploy() -> SyscallResult<(ContractAddress, Span)> { deploy_syscall(ZERO_CLASS_HASH, 0, array![].span(), false) } +fn deploy_v2() -> SyscallResult<(ContractAddress, Span)> { + deploy_v2_syscall(ZERO_CLASS_HASH, 0, array![].span(), false) +} + fn replace_class() -> SyscallResult<()> { replace_class_syscall(ZERO_CLASS_HASH) } diff --git a/tests/tests/starknet/box_arena.rs b/tests/tests/starknet/box_arena.rs index 6bdf6fbc17..e5f64601a8 100644 --- a/tests/tests/starknet/box_arena.rs +++ b/tests/tests/starknet/box_arena.rs @@ -107,6 +107,17 @@ impl StarknetSyscallHandler for &mut MultiContractHandler { ) -> SyscallResult<(Felt, Vec)> { unimplemented!() } + + fn deploy_v2( + &mut self, + _class_hash: Felt, + _contract_address_salt: Felt, + _calldata: &[Felt], + _deploy_from_zero: bool, + _remaining_gas: &mut u64, + ) -> SyscallResult<(Felt, Vec)> { + unimplemented!() + } fn replace_class(&mut self, _class_hash: Felt, _remaining_gas: &mut u64) -> SyscallResult<()> { unimplemented!() } diff --git a/tests/tests/starknet/secp256.rs b/tests/tests/starknet/secp256.rs index 6cc9e4ac28..61c3b7b073 100644 --- a/tests/tests/starknet/secp256.rs +++ b/tests/tests/starknet/secp256.rs @@ -70,6 +70,17 @@ impl StarknetSyscallHandler for &mut SyscallHandler { unimplemented!() } + fn deploy_v2( + &mut self, + _class_hash: Felt, + _contract_address_salt: Felt, + _calldata: &[Felt], + _deploy_from_zero: bool, + _remaining_gas: &mut u64, + ) -> SyscallResult<(Felt, Vec)> { + unimplemented!() + } + fn replace_class(&mut self, _class_hash: Felt, _remaining_gas: &mut u64) -> SyscallResult<()> { unimplemented!() } diff --git a/tests/tests/starknet/syscalls.rs b/tests/tests/starknet/syscalls.rs index 33d8d7bd62..358cfb8b4e 100644 --- a/tests/tests/starknet/syscalls.rs +++ b/tests/tests/starknet/syscalls.rs @@ -254,6 +254,23 @@ impl StarknetSyscallHandler for SyscallHandler { )) } + fn deploy_v2( + &mut self, + _class_hash: Felt, + _contract_address_salt: Felt, + _calldata: &[Felt], + _deploy_from_zero: bool, + _remaining_gas: &mut u64, + ) -> SyscallResult<(Felt, Vec)> { + // A distinct value from `deploy` (the salt-777 §3.1 frozen vector), so the JIT test + // confirms `deploy_v2_syscall` routes to this method and not to `deploy`. + Ok(( + Felt::from_hex("0x781e95f4b806dfe5b550756620c77a108d974a5b5d1198b1d45901ac1f89e9f") + .unwrap(), + Vec::new(), + )) + } + fn replace_class(&mut self, _class_hash: Felt, _remaining_gas: &mut u64) -> SyscallResult<()> { Ok(()) } @@ -934,6 +951,44 @@ fn deploy() { ) } +#[test] +fn deploy_v2() { + let program = load_program_and_runner("programs/starknet/syscalls"); + let result = run_native_program( + &program, + "deploy_v2", + &[], + Some(u64::MAX), + Some(SyscallHandler::new()), + ); + + // The salt-777 §3.1 frozen vector returned by the stub's `deploy_v2` — distinct from `deploy`'s + // return, confirming `deploy_v2_syscall` dispatches (via the DEPLOY_V2 vtable offset) to the + // handler's `deploy_v2` method. + assert_eq_sorted!( + result.return_value, + Value::Enum { + tag: 0, + value: Box::new(Value::Struct { + fields: vec![ + Value::Felt252( + Felt::from_hex( + "0x781e95f4b806dfe5b550756620c77a108d974a5b5d1198b1d45901ac1f89e9f", + ) + .unwrap() + ), + Value::Struct { + fields: vec![Value::Array(Vec::new())], + debug_name: None, + }, + ], + debug_name: None, + }), + debug_name: None, + }, + ) +} + #[test] fn replace_class() { let program = load_program_and_runner("programs/starknet/syscalls");