From 88938caa4aba5972e9238bcdc32c3ba7d97426f7 Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Fri, 25 Oct 2024 13:28:07 +0200 Subject: [PATCH 1/4] input read hints --- .gitignore | 2 + Cargo.lock | 1252 +++++++++++++++++ Cargo.toml | 21 + cairo_vm_hints/Cargo.toml | 20 + cairo_vm_hints/src/hint_processor/hints.rs | 174 +++ cairo_vm_hints/src/hint_processor/mod.rs | 130 ++ cairo_vm_hints/src/lib.rs | 2 + cairo_vm_hints/src/main.rs | 294 ++++ src/libs/mmr.cairo | 13 +- src/libs/utils.cairo | 53 +- .../chunk_processor.cairo | 50 +- tools/py/hints.py | 39 + 12 files changed, 1967 insertions(+), 83 deletions(-) create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 cairo_vm_hints/Cargo.toml create mode 100644 cairo_vm_hints/src/hint_processor/hints.rs create mode 100644 cairo_vm_hints/src/hint_processor/mod.rs create mode 100644 cairo_vm_hints/src/lib.rs create mode 100644 cairo_vm_hints/src/main.rs create mode 100644 tools/py/hints.py diff --git a/.gitignore b/.gitignore index 11c15cd..6e9d621 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,5 @@ package-lock.json src/.DS_Store solidity-verifier/lib/* + +target \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..93137d5 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,1252 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + +[[package]] +name = "anstream" +version = "0.6.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8365de52b16c035ff4fcafe0092ba9390540e3e352870ac09933bebcaa2c8c56" + +[[package]] +name = "anstyle-parse" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "anyhow" +version = "1.0.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8" + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "digest", + "itertools", + "num-bigint", + "num-traits", + "paste", + "rustc_version", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-std", + "digest", + "num-bigint", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand", +] + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "bincode" +version = "2.0.0-rc.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f11ea1a0346b94ef188834a65c068a03aec181c94896d481d7a0a40d85b0ce95" +dependencies = [ + "serde", +] + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cairo-vm" +version = "1.0.1" +source = "git+https://github.com/lambdaclass/cairo-vm?rev=3fb0344ce038b3a68cae897c403d1f561cfe8da7#3fb0344ce038b3a68cae897c403d1f561cfe8da7" +dependencies = [ + "anyhow", + "bincode", + "bitvec", + "clap", + "generic-array", + "hashbrown 0.14.5", + "hex", + "keccak", + "lazy_static", + "nom", + "num-bigint", + "num-integer", + "num-prime", + "num-traits", + "rand", + "rust_decimal", + "serde", + "serde_json", + "sha2", + "sha3", + "starknet-crypto 0.6.2", + "starknet-types-core", + "thiserror-no-std", + "wasm-bindgen", + "zip", +] + +[[package]] +name = "cairo_vm_hints" +version = "0.1.0" +source = "git+https://github.com/HerodotusDev/eth_essentials.git?rev=633bd7e23edd2aef9703078efd5a9e72bda95d3c#633bd7e23edd2aef9703078efd5a9e72bda95d3c" +dependencies = [ + "bincode", + "cairo-vm", + "clap", + "hex", + "num-bigint", + "num-traits", + "rand", + "sha3", + "starknet-crypto 0.7.2", + "starknet-types-core", + "thiserror", + "tiny-keccak", +] + +[[package]] +name = "cairo_vm_hints_processor" +version = "0.1.0" +dependencies = [ + "bincode", + "cairo-vm", + "cairo_vm_hints", + "clap", + "hex", + "num-bigint", + "num-traits", + "rand", + "serde_json", + "sha3", + "starknet-crypto 0.7.2", + "starknet-types-core", + "thiserror", + "tiny-keccak", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "4.5.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "clap_lex" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" + +[[package]] +name = "colorchoice" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" + +[[package]] +name = "cpufeatures" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "flate2" +version = "1.0.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "foldhash" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", + "serde", +] + +[[package]] +name = "hashbrown" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lambdaworks-crypto" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbc2a4da0d9e52ccfe6306801a112e81a8fc0c76aa3e4449fefeda7fef72bb34" +dependencies = [ + "lambdaworks-math", + "serde", + "sha2", + "sha3", +] + +[[package]] +name = "lambdaworks-math" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1bd2632acbd9957afc5aeec07ad39f078ae38656654043bf16e046fa2730e23" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin", +] + +[[package]] +name = "libc" +version = "0.2.161" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "lru" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" +dependencies = [ + "hashbrown 0.15.0", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", + "rand", + "serde", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-modular" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a5fe11d4135c3bcdf3a95b18b194afa9608a5f6ff034f5d857bc9a27fb0119" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-prime" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e238432a7881ec7164503ccc516c014bf009be7984cde1ba56837862543bdec3" +dependencies = [ + "bitvec", + "either", + "lru", + "num-bigint", + "num-integer", + "num-modular", + "num-traits", + "rand", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro2" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "rust_decimal" +version = "1.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b082d80e3e3cc52b2ed634388d436fe1f4de6af5786cc2de9ba9737527bdf555" +dependencies = [ + "arrayvec", + "num-traits", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + +[[package]] +name = "serde" +version = "1.0.213" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ea7893ff5e2466df8d720bb615088341b295f849602c6956047f8f80f0e9bc1" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.213" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e85ad2009c50b58e87caa8cd6dac16bdf511bbfb7af6c33df902396aa480fa5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "serde_json" +version = "1.0.132" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest", + "keccak", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "starknet-crypto" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e2c30c01e8eb0fc913c4ee3cf676389fffc1d1182bfe5bb9670e4e72e968064" +dependencies = [ + "crypto-bigint", + "hex", + "hmac", + "num-bigint", + "num-integer", + "num-traits", + "rfc6979", + "sha2", + "starknet-crypto-codegen", + "starknet-curve 0.4.2", + "starknet-ff", + "zeroize", +] + +[[package]] +name = "starknet-crypto" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a5064173a8e8d2675e67744fd07f310de44573924b6b7af225a6bdd8102913" +dependencies = [ + "crypto-bigint", + "hex", + "hmac", + "num-bigint", + "num-integer", + "num-traits", + "rfc6979", + "sha2", + "starknet-curve 0.5.1", + "starknet-types-core", + "zeroize", +] + +[[package]] +name = "starknet-crypto-codegen" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbc159a1934c7be9761c237333a57febe060ace2bc9e3b337a59a37af206d19f" +dependencies = [ + "starknet-curve 0.4.2", + "starknet-ff", + "syn 2.0.85", +] + +[[package]] +name = "starknet-curve" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1c383518bb312751e4be80f53e8644034aa99a0afb29d7ac41b89a997db875b" +dependencies = [ + "starknet-ff", +] + +[[package]] +name = "starknet-curve" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcde6bd74269b8161948190ace6cf069ef20ac6e79cd2ba09b320efa7500b6de" +dependencies = [ + "starknet-types-core", +] + +[[package]] +name = "starknet-ff" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abf1b44ec5b18d87c1ae5f54590ca9d0699ef4dd5b2ffa66fc97f24613ec585" +dependencies = [ + "ark-ff", + "crypto-bigint", + "getrandom", + "hex", +] + +[[package]] +name = "starknet-types-core" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa1b9e01ccb217ab6d475c5cda05dbb22c30029f7bb52b192a010a00d77a3d74" +dependencies = [ + "lambdaworks-crypto", + "lambdaworks-math", + "num-bigint", + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "thiserror" +version = "1.0.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "thiserror-impl-no-std" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58e6318948b519ba6dc2b442a6d0b904ebfb8d411a3ad3e07843615a72249758" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "thiserror-no-std" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3ad459d94dd517257cc96add8a43190ee620011bb6e6cdc82dafd97dfafafea" +dependencies = [ + "thiserror-impl-no-std", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.85", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "zip" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" +dependencies = [ + "byteorder", + "crc32fast", + "crossbeam-utils", + "flate2", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..69daccd --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,21 @@ +[workspace] +resolver = "2" + +members = ["cairo_vm_hints"] + + +[workspace.dependencies] +bincode = { version = "2.0.0-rc.3", default-features = false, features = ["serde"] } +cairo-vm = { git = "https://github.com/lambdaclass/cairo-vm", rev = "3fb0344ce038b3a68cae897c403d1f561cfe8da7", features = ["extensive_hints", "clap", "std"] } +clap = { version = "4.3.10", features = ["derive"] } +rand = "0.8" +sha3 = "0.10.8" +starknet-types-core = "0.1.7" +thiserror = "1.0.64" +num-bigint = "0.4.6" +num-traits = "0.2.19" +tiny-keccak = { version = "2.0.2", features = ["keccak"] } +hex = "0.4.3" +starknet-crypto = "0.7.2" +cairo_vm_hints = { git = "https://github.com/HerodotusDev/eth_essentials.git", rev = "633bd7e23edd2aef9703078efd5a9e72bda95d3c" } +serde_json = "1.0.132" \ No newline at end of file diff --git a/cairo_vm_hints/Cargo.toml b/cairo_vm_hints/Cargo.toml new file mode 100644 index 0000000..5e7c041 --- /dev/null +++ b/cairo_vm_hints/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "cairo_vm_hints_processor" +version = "0.1.0" +edition = "2021" + +[dependencies] +bincode.workspace = true +cairo-vm.workspace = true +clap.workspace = true +rand.workspace = true +sha3.workspace = true +starknet-types-core.workspace = true +thiserror.workspace = true +num-bigint.workspace = true +num-traits.workspace = true +tiny-keccak.workspace = true +hex.workspace = true +starknet-crypto.workspace = true +cairo_vm_hints.workspace = true +serde_json.workspace = true \ No newline at end of file diff --git a/cairo_vm_hints/src/hint_processor/hints.rs b/cairo_vm_hints/src/hint_processor/hints.rs new file mode 100644 index 0000000..1587bc8 --- /dev/null +++ b/cairo_vm_hints/src/hint_processor/hints.rs @@ -0,0 +1,174 @@ +use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::get_ptr_from_var_name; +use cairo_vm::types::relocatable::MaybeRelocatable; +use cairo_vm::{ + hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData, + types::exec_scope::ExecutionScopes, + vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, + Felt252, +}; +use cairo_vm_hints::utils; +use std::collections::HashMap; + +use super::CustomHintProcessor; + +pub const HINT_READ_INPUT: &str = "ids.from_block_number_high=program_input['from_block_number_high']\nids.to_block_number_low=program_input['to_block_number_low']\nids.mmr_offset=program_input['mmr_last_len'] \nids.mmr_last_root_poseidon=program_input['mmr_last_root_poseidon']\nids.mmr_last_root_keccak.low=program_input['mmr_last_root_keccak_low']\nids.mmr_last_root_keccak.high=program_input['mmr_last_root_keccak_high']\nids.block_n_plus_one_parent_hash_little.low = program_input['block_n_plus_one_parent_hash_little_low']\nids.block_n_plus_one_parent_hash_little.high = program_input['block_n_plus_one_parent_hash_little_high']"; +pub const HINT_READ_INPUT_PREV: &str = "segments.write_arg(ids.previous_peaks_values_poseidon, program_input['poseidon_mmr_last_peaks']) \nwrite_uint256_array(ids.previous_peaks_values_keccak, program_input['keccak_mmr_last_peaks'])"; +pub const HINT_READ_BLOCK_HEADERS: &str = "block_headers_array = program_input['block_headers_array']\nbytes_len_array = program_input['bytes_len_array']\nsegments.write_arg(ids.block_headers_array, block_headers_array)\nsegments.write_arg(ids.block_headers_array_bytes_len, bytes_len_array)"; + +impl CustomHintProcessor { + pub fn hint_read_input( + &mut self, + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, + ) -> Result<(), HintError> { + let from_block_number_high: Felt252 = + serde_json::from_value(self.private_inputs["from_block_number_high"].clone()).unwrap(); + let to_block_number_low: Felt252 = + serde_json::from_value(self.private_inputs["to_block_number_low"].clone()).unwrap(); + let mmr_offset: Felt252 = + serde_json::from_value(self.private_inputs["mmr_offset"].clone()).unwrap(); + let mmr_last_root_poseidon: Felt252 = + serde_json::from_value(self.private_inputs["mmr_last_root_poseidon"].clone()).unwrap(); + let mmr_last_root_keccak_low: Felt252 = + serde_json::from_value(self.private_inputs["mmr_last_root_keccak_low"].clone()) + .unwrap(); + let mmr_last_root_keccak_high: Felt252 = + serde_json::from_value(self.private_inputs["mmr_last_root_keccak_high"].clone()) + .unwrap(); + let block_n_plus_one_parent_hash_little_low: Felt252 = serde_json::from_value( + self.private_inputs["block_n_plus_one_parent_hash_little_low"].clone(), + ) + .unwrap(); + let block_n_plus_one_parent_hash_little_high: Felt252 = serde_json::from_value( + self.private_inputs["block_n_plus_one_parent_hash_little_high"].clone(), + ) + .unwrap(); + + utils::write_value( + "from_block_number_high", + MaybeRelocatable::Int(from_block_number_high), + vm, + hint_data, + )?; + utils::write_value( + "to_block_number_low", + MaybeRelocatable::Int(to_block_number_low), + vm, + hint_data, + )?; + utils::write_value( + "mmr_offset", + MaybeRelocatable::Int(mmr_offset), + vm, + hint_data, + )?; + utils::write_value( + "mmr_last_root_poseidon", + MaybeRelocatable::Int(mmr_last_root_poseidon), + vm, + hint_data, + )?; + utils::write_value( + "mmr_last_root_poseidon", + MaybeRelocatable::Int(mmr_last_root_poseidon), + vm, + hint_data, + )?; + utils::write_struct( + "mmr_last_root_keccak", + &[mmr_last_root_keccak_low, mmr_last_root_keccak_high] + .into_iter() + .map(MaybeRelocatable::Int) + .collect::>(), + vm, + hint_data, + )?; + utils::write_struct( + "block_n_plus_one_parent_hash_little", + &[ + block_n_plus_one_parent_hash_little_low, + block_n_plus_one_parent_hash_little_high, + ] + .into_iter() + .map(MaybeRelocatable::Int) + .collect::>(), + vm, + hint_data, + )?; + + Ok(()) + } + + pub fn hint_read_input_prev( + &mut self, + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, + ) -> Result<(), HintError> { + let poseidon_mmr_last_peaks: Vec = + serde_json::from_value(self.private_inputs["poseidon_mmr_last_peaks"].clone()).unwrap(); + + let keccak_mmr_last_peaks: Vec> = + serde_json::from_value(self.private_inputs["keccak_mmr_last_peaks"].clone()).unwrap(); + + let previous_peaks_values_poseidon_ptr = get_ptr_from_var_name( + "previous_peaks_values_poseidon", + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + let previous_peaks_values_keccak_ptr = get_ptr_from_var_name( + "previous_peaks_values_keccak", + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + vm.segments + .write_arg(previous_peaks_values_poseidon_ptr, &poseidon_mmr_last_peaks)?; + + vm.segments + .write_arg(previous_peaks_values_keccak_ptr, &keccak_mmr_last_peaks)?; + + Ok(()) + } + + pub fn hint_read_block_headers( + &mut self, + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, + ) -> Result<(), HintError> { + let block_headers_array: Vec> = + serde_json::from_value(self.private_inputs["block_headers_array"].clone()).unwrap(); + + let bytes_len_array: Vec = + serde_json::from_value(self.private_inputs["bytes_len_array"].clone()).unwrap(); + + let block_headers_array_ptr = get_ptr_from_var_name( + "block_headers_array", + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + let block_headers_array_bytes_len_ptr = get_ptr_from_var_name( + "block_headers_array_bytes_len", + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + vm.segments + .write_arg(block_headers_array_ptr, &block_headers_array)?; + vm.segments + .write_arg(block_headers_array_bytes_len_ptr, &bytes_len_array)?; + + Ok(()) + } +} diff --git a/cairo_vm_hints/src/hint_processor/mod.rs b/cairo_vm_hints/src/hint_processor/mod.rs new file mode 100644 index 0000000..80c2b6b --- /dev/null +++ b/cairo_vm_hints/src/hint_processor/mod.rs @@ -0,0 +1,130 @@ +use cairo_vm::{ + hint_processor::{ + builtin_hint_processor::builtin_hint_processor_definition::{ + BuiltinHintProcessor, HintFunc, HintProcessorData, + }, + hint_processor_definition::HintExtension, + hint_processor_definition::HintProcessorLogic, + }, + types::exec_scope::ExecutionScopes, + vm::{ + errors::hint_errors::HintError, runners::cairo_runner::ResourceTracker, + vm_core::VirtualMachine, + }, + Felt252, +}; +use starknet_types_core::felt::Felt; +use std::collections::HashMap; +use std::{any::Any, rc::Rc}; + +pub mod hints; + +#[derive(Default)] +pub struct CustomHintProcessor { + pub private_inputs: serde_json::Value, +} + +impl CustomHintProcessor { + pub fn new(private_inputs: serde_json::Value) -> Self { + Self { private_inputs } + } + + pub fn run_hint( + &mut self, + vm: &mut VirtualMachine, + exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + constants: &HashMap, + ) -> Result<(), HintError> { + match hint_data.code.as_str() { + hints::HINT_READ_BLOCK_HEADERS => { + self.hint_read_block_headers(vm, exec_scope, hint_data, constants) + } + _ => Err(HintError::UnknownHint( + hint_data.code.to_string().into_boxed_str(), + )), + } + } +} + +impl HintProcessorLogic for CustomHintProcessor { + fn execute_hint( + &mut self, + vm: &mut VirtualMachine, + exec_scopes: &mut ExecutionScopes, + hint_data: &Box, + constants: &HashMap, + ) -> Result<(), HintError> { + let hint_data = hint_data + .downcast_ref::() + .ok_or(HintError::WrongHintData)?; + + cairo_vm_hints::hints::run_hint(vm, exec_scopes, hint_data, constants)?; + self.run_hint(vm, exec_scopes, hint_data, constants) + } +} + +impl ResourceTracker for CustomHintProcessor {} + +pub struct ExtendedHintProcessor { + custom_hint_processor: CustomHintProcessor, + builtin_hint_processor: BuiltinHintProcessor, +} + +impl Default for ExtendedHintProcessor { + fn default() -> Self { + Self::new(serde_json::Value::default()) + } +} + +impl ExtendedHintProcessor { + pub fn new(private_inputs: serde_json::Value) -> Self { + Self { + custom_hint_processor: CustomHintProcessor { private_inputs }, + builtin_hint_processor: BuiltinHintProcessor::new_empty(), + } + } + + pub fn add_hint(&mut self, hint_code: String, hint_func: Rc) { + self.builtin_hint_processor + .extra_hints + .insert(hint_code, hint_func); + } +} + +impl HintProcessorLogic for ExtendedHintProcessor { + fn execute_hint( + &mut self, + _vm: &mut VirtualMachine, + _exec_scopes: &mut ExecutionScopes, + _hint_data: &Box, + _constants: &HashMap, + ) -> Result<(), HintError> { + unreachable!(); + } + + fn execute_hint_extensive( + &mut self, + vm: &mut VirtualMachine, + exec_scopes: &mut ExecutionScopes, + hint_data: &Box, + constants: &HashMap, + ) -> Result { + match self.custom_hint_processor.execute_hint_extensive( + vm, + exec_scopes, + hint_data, + constants, + ) { + Err(HintError::UnknownHint(_)) => {} + result => { + return result; + } + } + + self.builtin_hint_processor + .execute_hint_extensive(vm, exec_scopes, hint_data, constants) + } +} + +impl ResourceTracker for ExtendedHintProcessor {} diff --git a/cairo_vm_hints/src/lib.rs b/cairo_vm_hints/src/lib.rs new file mode 100644 index 0000000..4c0f40a --- /dev/null +++ b/cairo_vm_hints/src/lib.rs @@ -0,0 +1,2 @@ +pub mod hint_processor; +pub use hint_processor::{CustomHintProcessor, ExtendedHintProcessor}; diff --git a/cairo_vm_hints/src/main.rs b/cairo_vm_hints/src/main.rs new file mode 100644 index 0000000..414f74d --- /dev/null +++ b/cairo_vm_hints/src/main.rs @@ -0,0 +1,294 @@ +#![deny(warnings)] +#![forbid(unsafe_code)] +use bincode::enc::write::Writer; +use cairo_vm::air_public_input::PublicInputError; +use cairo_vm::cairo_run::{self, EncodeTraceError}; +use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::BuiltinHintProcessor; +// TODO +// #[cfg(feature = "with_tracer")] +// use cairo_vm::serde::deserialize_program::DebugInfo; +use cairo_vm::types::layout::CairoLayoutParams; +use cairo_vm::types::layout_name::LayoutName; +use cairo_vm::vm::errors::cairo_run_errors::CairoRunError; +use cairo_vm::vm::errors::trace_errors::TraceError; +use cairo_vm::vm::errors::vm_errors::VirtualMachineError; +use cairo_vm::vm::runners::cairo_pie::CairoPie; +// #[cfg(feature = "with_tracer")] +// use cairo_vm::vm::runners::cairo_runner::CairoRunner; +use cairo_vm::vm::runners::cairo_runner::RunResources; +use cairo_vm_hints_processor::hint_processor::ExtendedHintProcessor; +// #[cfg(feature = "with_tracer")] +// use cairo_vm_tracer::error::trace_data_errors::TraceDataError; +// #[cfg(feature = "with_tracer")] +// use cairo_vm_tracer::tracer::run_tracer; +use clap::{Parser, ValueHint}; +use std::fs; +use std::io::{self, Write}; +use std::path::{Path, PathBuf}; +use thiserror::Error; + +// #[cfg(feature = "with_mimalloc")] +// use mimalloc::MiMalloc; + +// #[cfg(feature = "with_mimalloc")] +// #[global_allocator] +// static ALLOC: MiMalloc = MiMalloc; + +#[derive(Parser, Debug)] +#[clap(author, version, about, long_about = None)] +struct Args { + #[clap(value_parser, value_hint=ValueHint::FilePath)] + filename: PathBuf, + #[clap(long = "trace_file", value_parser)] + trace_file: Option, + #[structopt(long = "print_output")] + print_output: bool, + #[structopt(long = "entrypoint", default_value = "main")] + entrypoint: String, + #[structopt(long = "memory_file")] + memory_file: Option, + /// When using dynamic layout, it's parameters must be specified through a layout params file. + #[clap(long = "layout", default_value = "plain", value_enum)] + layout: LayoutName, + /// Required when using with dynamic layout. + /// Ignored otherwise. + #[clap(long = "cairo_layout_params_file", required_if_eq("layout", "dynamic"))] + cairo_layout_params_file: Option, + #[structopt(long = "proof_mode")] + proof_mode: bool, + #[structopt(long = "secure_run")] + secure_run: Option, + #[structopt(long = "program_input")] + program_input: Option, + #[clap(long = "air_public_input", requires = "proof_mode")] + air_public_input: Option, + #[clap( + long = "air_private_input", + requires_all = ["proof_mode", "trace_file", "memory_file"] + )] + air_private_input: Option, + #[clap( + long = "cairo_pie_output", + // We need to add these air_private_input & air_public_input or else + // passing cairo_pie_output + either of these without proof_mode will not fail + conflicts_with_all = ["proof_mode", "air_private_input", "air_public_input"] + )] + cairo_pie_output: Option, + #[structopt(long = "allow_missing_builtins")] + allow_missing_builtins: Option, + #[structopt(long = "tracer")] + // #[cfg(feature = "with_tracer")] + // tracer: bool, + #[structopt( + long = "run_from_cairo_pie", + // We need to add these air_private_input & air_public_input or else + // passing run_from_cairo_pie + either of these without proof_mode will not fail + conflicts_with_all = ["proof_mode", "air_private_input", "air_public_input"] + )] + run_from_cairo_pie: bool, +} + +#[derive(Debug, Error)] +enum Error { + #[error("Invalid arguments")] + Cli(#[from] clap::Error), + #[error("Failed to interact with the file system")] + IO(#[from] std::io::Error), + #[error("The cairo program execution failed")] + Runner(#[from] CairoRunError), + #[error(transparent)] + EncodeTrace(#[from] EncodeTraceError), + #[error(transparent)] + VirtualMachine(#[from] VirtualMachineError), + #[error(transparent)] + Trace(#[from] TraceError), + #[error(transparent)] + PublicInput(#[from] PublicInputError), + // #[error(transparent)] + // #[cfg(feature = "with_tracer")] + // TraceData(#[from] TraceDataError), +} + +struct FileWriter { + buf_writer: io::BufWriter, + bytes_written: usize, +} + +impl Writer for FileWriter { + fn write(&mut self, bytes: &[u8]) -> Result<(), bincode::error::EncodeError> { + self.buf_writer + .write_all(bytes) + .map_err(|e| bincode::error::EncodeError::Io { + inner: e, + index: self.bytes_written, + })?; + + self.bytes_written += bytes.len(); + + Ok(()) + } +} + +impl FileWriter { + fn new(buf_writer: io::BufWriter) -> Self { + Self { + buf_writer, + bytes_written: 0, + } + } + + fn flush(&mut self) -> io::Result<()> { + self.buf_writer.flush() + } +} + +// #[cfg(feature = "with_tracer")] +// fn start_tracer(cairo_runner: &CairoRunner) -> Result<(), TraceDataError> { +// let relocation_table = cairo_runner +// .vm +// .relocate_segments() +// .map_err(TraceDataError::FailedToGetRelocationTable)?; +// let instruction_locations = cairo_runner +// .get_program() +// .get_relocated_instruction_locations(relocation_table.as_ref()); +// let debug_info = instruction_locations.map(DebugInfo::new); + +// let relocated_trace = cairo_runner +// .relocated_trace +// .clone() +// .ok_or(TraceDataError::FailedToGetRelocatedTrace)?; + +// run_tracer( +// cairo_runner.get_program().clone(), +// cairo_runner.relocated_memory.clone(), +// relocated_trace.clone(), +// 1, +// debug_info, +// )?; +// Ok(()) +// } + +fn run(args: impl Iterator) -> Result<(), Error> { + let args = Args::try_parse_from(args)?; + + let trace_enabled = args.trace_file.is_some() || args.air_public_input.is_some(); + + let cairo_layout_params = match args.cairo_layout_params_file { + Some(file) => Some(CairoLayoutParams::from_file(&file)?), + None => None, + }; + + let cairo_run_config = cairo_run::CairoRunConfig { + entrypoint: &args.entrypoint, + trace_enabled, + relocate_mem: args.memory_file.is_some() || args.air_public_input.is_some(), + layout: args.layout, + proof_mode: args.proof_mode, + secure_run: args.secure_run, + allow_missing_builtins: args.allow_missing_builtins, + dynamic_layout_params: cairo_layout_params, + ..Default::default() + }; + + let mut cairo_runner = match if args.run_from_cairo_pie { + let pie = CairoPie::read_zip_file(&args.filename)?; + let mut hint_processor = BuiltinHintProcessor::new( + Default::default(), + RunResources::new(pie.execution_resources.n_steps), + ); + cairo_run::cairo_run_pie(&pie, &cairo_run_config, &mut hint_processor) + } else { + let program_content = std::fs::read(args.filename).map_err(Error::IO)?; + let mut hint_processor = ExtendedHintProcessor::new( + serde_json::from_slice(&fs::read(args.program_input.unwrap()).unwrap()).unwrap(), + ); + cairo_run::cairo_run(&program_content, &cairo_run_config, &mut hint_processor) + } { + Ok(runner) => runner, + Err(error) => { + eprintln!("{error}"); + return Err(Error::Runner(error)); + } + }; + + if args.print_output { + let mut output_buffer = "Program Output:\n".to_string(); + cairo_runner.vm.write_output(&mut output_buffer)?; + print!("{output_buffer}"); + } + + if let Some(ref trace_path) = args.trace_file { + let relocated_trace = cairo_runner + .relocated_trace + .as_ref() + .ok_or(Error::Trace(TraceError::TraceNotRelocated))?; + + let trace_file = std::fs::File::create(trace_path)?; + let mut trace_writer = + FileWriter::new(io::BufWriter::with_capacity(3 * 1024 * 1024, trace_file)); + + cairo_run::write_encoded_trace(relocated_trace, &mut trace_writer)?; + trace_writer.flush()?; + } + + if let Some(ref memory_path) = args.memory_file { + let memory_file = std::fs::File::create(memory_path)?; + let mut memory_writer = + FileWriter::new(io::BufWriter::with_capacity(5 * 1024 * 1024, memory_file)); + + cairo_run::write_encoded_memory(&cairo_runner.relocated_memory, &mut memory_writer)?; + memory_writer.flush()?; + } + + if let Some(file_path) = args.air_public_input { + let json = cairo_runner.get_air_public_input()?.serialize_json()?; + std::fs::write(file_path, json)?; + } + + // #[cfg(feature = "with_tracer")] + // if args.tracer { + // start_tracer(&cairo_runner)?; + // } + + if let (Some(file_path), Some(ref trace_file), Some(ref memory_file)) = + (args.air_private_input, args.trace_file, args.memory_file) + { + // Get absolute paths of trace_file & memory_file + let trace_path = trace_file + .as_path() + .canonicalize() + .unwrap_or(trace_file.clone()) + .to_string_lossy() + .to_string(); + let memory_path = memory_file + .as_path() + .canonicalize() + .unwrap_or(memory_file.clone()) + .to_string_lossy() + .to_string(); + + let json = cairo_runner + .get_air_private_input() + .to_serializable(trace_path, memory_path) + .serialize_json() + .map_err(PublicInputError::Serde)?; + std::fs::write(file_path, json)?; + } + + if let Some(ref file_name) = args.cairo_pie_output { + let file_path = Path::new(file_name); + cairo_runner + .get_cairo_pie() + .map_err(CairoRunError::Runner)? + .write_zip_file(file_path)? + } + + Ok(()) +} + +fn main() -> Result<(), Error> { + match run(std::env::args()) { + Err(Error::Cli(err)) => err.exit(), + other => other, + } +} diff --git a/src/libs/mmr.cairo b/src/libs/mmr.cairo index aa9cfaa..be8458d 100644 --- a/src/libs/mmr.cairo +++ b/src/libs/mmr.cairo @@ -99,10 +99,8 @@ func is_valid_mmr_size_inner{range_check_ptr, pow2_array: felt*}(n: felt, prev_p func compute_height_pre_alloc_pow2{range_check_ptr, pow2_array: felt*}(x: felt) -> felt { alloc_locals; local bit_length; - %{ - x = ids.x - ids.bit_length = x.bit_length() - %} + %{ ids.bit_length = ids.x.bit_length() %} + // Computes N=2^bit_length and n=2^(bit_length-1) // x is supposed to verify n = 2^(b-1) <= x < N = 2^bit_length <=> x has bit_length bits @@ -143,10 +141,7 @@ func compute_height_pre_alloc_pow2{range_check_ptr, pow2_array: felt*}(x: felt) func compute_first_peak_pos{range_check_ptr, pow2_array: felt*}(mmr_len: felt) -> felt { alloc_locals; local bit_length; - %{ - mmr_len = ids.mmr_len - ids.bit_length = mmr_len.bit_length() - %} + %{ ids.bit_length = ids.mmr_len.bit_length() %} // Computes N=2^bit_length and n=2^(bit_length-1) // x is supposed to verify n = 2^(b-1) <= x < N = 2^bit_length <=> x has bit_length bits @@ -238,8 +233,8 @@ func left_child_jump_until_inside_mmr{range_check_ptr, pow2_array: felt*, mmr_le ) -> felt { alloc_locals; local in_mmr; - %{ ids.in_mmr = 1 if ids.left_child<=ids.mmr_len else 0 %} + if (in_mmr != 0) { // Ensure left_child <= mmr_len assert [range_check_ptr] = mmr_len - left_child; diff --git a/src/libs/utils.cairo b/src/libs/utils.cairo index c41fa89..d153764 100644 --- a/src/libs/utils.cairo +++ b/src/libs/utils.cairo @@ -18,10 +18,7 @@ const DIV_32_MINUS_1 = DIV_32 - 1; func get_felt_bitlength{range_check_ptr, pow2_array: felt*}(x: felt) -> felt { alloc_locals; local bit_length; - %{ - x = ids.x - ids.bit_length = x.bit_length() - %} + %{ ids.bit_length = ids.x.bit_length() %} // Computes N=2^bit_length and n=2^(bit_length-1) // x is supposed to verify n = 2^(b-1) <= x < N = 2^bit_length <=> x has bit_length bits tempvar N = pow2_array[bit_length]; @@ -65,10 +62,10 @@ func felt_divmod_2pow32{range_check_ptr}(value: felt) -> (q: felt, r: felt) { %{ from starkware.cairo.common.math_utils import assert_integer assert_integer(ids.DIV_32) - assert 0 < ids.DIV_32 <= PRIME // range_check_builtin.bound, \ - f'div={hex(ids.DIV_32)} is out of the valid range.' - ids.q, ids.r = divmod(ids.value, ids.DIV_32) + if not (0 < ids.DIV_32 <= PRIME): + raise ValueError(f'div={hex(ids.DIV_32)} is out of the valid range.') %} + %{ ids.q, ids.r = divmod(ids.value, ids.DIV_32) %} assert [range_check_ptr + 2] = DIV_32_MINUS_1 - r; let range_check_ptr = range_check_ptr + 3; @@ -110,11 +107,8 @@ func word_reverse_endian_64{bitwise_ptr: BitwiseBuiltin*}(word: felt) -> (res: f // res: the reversed integer. func word_reverse_endian_16_RC{range_check_ptr}(word: felt) -> felt { %{ - word = ids.word - assert word < 2**16 - word_bytes=word.to_bytes(2, byteorder='big') - for i in range(2): - memory[ap+i] = word_bytes[i] + from tools.py.hints import write_word_to_memory + write_word_to_memory(ids.word, 2, memory, ap) %} ap += 2; @@ -140,11 +134,8 @@ func word_reverse_endian_16_RC{range_check_ptr}(word: felt) -> felt { // res: the reversed integer. func word_reverse_endian_24_RC{range_check_ptr}(word: felt) -> felt { %{ - word = ids.word - assert word < 2**24 - word_bytes=word.to_bytes(3, byteorder='big') - for i in range(3): - memory[ap+i] = word_bytes[i] + from tools.py.hints import write_word_to_memory + write_word_to_memory(ids.word, 3, memory, ap) %} ap += 3; @@ -173,11 +164,8 @@ func word_reverse_endian_24_RC{range_check_ptr}(word: felt) -> felt { // res: the reversed integer. func word_reverse_endian_32_RC{range_check_ptr}(word: felt) -> felt { %{ - word = ids.word - assert word < 2**32 - word_bytes=word.to_bytes(4, byteorder='big') - for i in range(4): - memory[ap+i] = word_bytes[i] + from tools.py.hints import write_word_to_memory + write_word_to_memory(ids.word, 4, memory, ap) %} ap += 4; @@ -209,11 +197,8 @@ func word_reverse_endian_32_RC{range_check_ptr}(word: felt) -> felt { // res: the reversed integer. func word_reverse_endian_40_RC{range_check_ptr}(word: felt) -> felt { %{ - word = ids.word - assert word < 2**40 - word_bytes=word.to_bytes(5, byteorder='big') - for i in range(5): - memory[ap+i] = word_bytes[i] + from tools.py.hints import write_word_to_memory + write_word_to_memory(ids.word, 5, memory, ap) %} ap += 5; @@ -248,11 +233,8 @@ func word_reverse_endian_40_RC{range_check_ptr}(word: felt) -> felt { // res: the reversed integer. func word_reverse_endian_48_RC{range_check_ptr}(word: felt) -> felt { %{ - word = ids.word - assert word < 2**48 - word_bytes=word.to_bytes(6, byteorder='big') - for i in range(6): - memory[ap+i] = word_bytes[i] + from tools.py.hints import write_word_to_memory + write_word_to_memory(ids.word, 6, memory, ap) %} ap += 6; @@ -290,11 +272,8 @@ func word_reverse_endian_48_RC{range_check_ptr}(word: felt) -> felt { // res: the reversed integer. func word_reverse_endian_56_RC{range_check_ptr}(word: felt) -> felt { %{ - word = ids.word - assert word < 2**56 - word_bytes=word.to_bytes(7, byteorder='big') - for i in range(7): - memory[ap+i] = word_bytes[i] + from tools.py.hints import write_word_to_memory + write_word_to_memory(ids.word, 7, memory, ap) %} ap += 7; diff --git a/src/single_chunk_processor/chunk_processor.cairo b/src/single_chunk_processor/chunk_processor.cairo index df31837..681063b 100644 --- a/src/single_chunk_processor/chunk_processor.cairo +++ b/src/single_chunk_processor/chunk_processor.cairo @@ -69,9 +69,12 @@ func verify_block_headers_and_hash_them{ assert 0 = block_header_hash_little.low - expected_block_hash.low; assert 0 = block_header_hash_little.high - expected_block_hash.high; - %{ print("\n") %} - %{ print_u256(ids.block_header_hash_little,f"block_header_keccak_hash_{ids.index}") %} - %{ print_u256(ids.expected_block_hash,f"expected_keccak_hash_{ids.index}") %} + %{ + from tools.py.hints import print_u256 + print("\n") + print_u256(ids.block_header_hash_little,f"block_header_keccak_hash_{ids.index}") + print_u256(ids.expected_block_hash,f"expected_keccak_hash_{ids.index}") + %} let (number_of_exact_8bytes_chunks, number_of_bytes_in_last_chunk) = felt_divmod( bytes_len_array[index], 8 @@ -266,36 +269,6 @@ func main{ ids.block_n_plus_one_parent_hash_little.low = program_input['block_n_plus_one_parent_hash_little_low'] ids.block_n_plus_one_parent_hash_little.high = program_input['block_n_plus_one_parent_hash_little_high'] %} - %{ - def print_u256(u, un): - u = u.low + (u.high << 128) - print(f" {un} = {hex(u)}") - def write_uint256_array(ptr, array): - counter = 0 - for uint in array: - memory[ptr._reference_value+counter] = uint[0] - memory[ptr._reference_value+counter+1] = uint[1] - counter += 2 - def print_block_header(block_headers_array, bytes_len_array, index): - rlp_ptr = memory[block_headers_array + index] - n_bytes= memory[bytes_len_array + index] - n_felts = n_bytes // 8 + 1 if n_bytes % 8 != 0 else n_bytes // 8 - rlp_array = [memory[rlp_ptr + i] for i in range(n_felts)] - rlp_bytes_array=[int.to_bytes(x, 8, "big") for x in rlp_array] - rlp_bytes_array_little = [int.to_bytes(x, 8, "little") for x in rlp_array] - rlp_array_little = [int.from_bytes(x, 'little') for x in rlp_bytes_array] - x=[x.bit_length() for x in rlp_array] - print(f"\nBLOCK {index} :: bytes_len={n_bytes} || n_felts={n_felts}") - print(f"RLP_felt ={rlp_array}") - print(f"bit_big : {[x.bit_length() for x in rlp_array]}") - print(f"RLP_bytes_arr_big = {rlp_bytes_array}") - print(f"RLP_bytes_arr_lil = {rlp_bytes_array_little}") - print(f"bit_lil : {[x.bit_length() for x in rlp_array_little]}") - def print_mmr(mmr_array, mmr_array_len): - print(f"\nMMR :: mmr_array_len={mmr_array_len}") - mmr_values = [hex(memory[mmr_array + i]) for i in range(mmr_array_len)] - print(f"mmr_values = {mmr_values}") - %} // ----------------------------------------------------- // ----------------------------------------------------- @@ -313,8 +286,9 @@ func main{ let (previous_peaks_values_keccak: Uint256*) = alloc(); // From left to right %{ + from tools.py.hints import write_uint256_array segments.write_arg(ids.previous_peaks_values_poseidon, program_input['poseidon_mmr_last_peaks']) - write_uint256_array(ids.previous_peaks_values_keccak, program_input['keccak_mmr_last_peaks']) + write_uint256_array(memory, ids.previous_peaks_values_keccak, program_input['keccak_mmr_last_peaks']) %} // Ensure that the previous MMR size is valid. @@ -422,9 +396,11 @@ func main{ let (new_mmr_root_poseidon: felt, new_mmr_root_keccak: Uint256) = get_roots(); } - %{ print("new root poseidon", ids.new_mmr_root_poseidon) %} - %{ print("new root keccak", ids.new_mmr_root_keccak.low, ids.new_mmr_root_keccak.high) %} - %{ print("new size", ids.mmr_array_len + ids.mmr_offset) %} + %{ + print("new root poseidon", ids.new_mmr_root_poseidon) + print("new root keccak", ids.new_mmr_root_keccak.low, ids.new_mmr_root_keccak.high) + print("new size", ids.mmr_array_len + ids.mmr_offset) + %} default_dict_finalize(dict_start_poseidon, previous_peaks_dict_poseidon, 0); default_dict_finalize(dict_start_keccak, previous_peaks_dict_keccak, 0); diff --git a/tools/py/hints.py b/tools/py/hints.py new file mode 100644 index 0000000..939361f --- /dev/null +++ b/tools/py/hints.py @@ -0,0 +1,39 @@ +def write_word_to_memory(word: int, n: int, memory, ap) -> None: + assert word < 2 ** (8 * n), f"Word value {word} exceeds {8 * n} bits." + word_bytes = word.to_bytes(n, byteorder="big") + for i in range(n): + memory[ap + i] = word_bytes[i] + +def print_u256(x, name): + value = x.low + (x.high << 128) + print(f"{name} = {hex(value)}") + + +def write_uint256_array(memory, ptr, array): + for i, uint in enumerate(array): + memory[ptr._reference_value + 2 * i] = uint[0] + memory[ptr._reference_value + 2 * i + 1] = uint[1] + + +def print_block_header(memory, block_headers_array, bytes_len_array, index): + rlp_ptr = memory[block_headers_array + index] + n_bytes = memory[bytes_len_array + index] + n_felts = -(-n_bytes // 8) # Equivalent to ceiling division + + rlp_array = [memory[rlp_ptr + i] for i in range(n_felts)] + rlp_bytes_big_endian = [x.to_bytes(8, "big") for x in rlp_array] + rlp_bytes_little_endian = [x.to_bytes(8, "little") for x in rlp_array] + rlp_array_little = [int.from_bytes(b, 'little') for b in rlp_bytes_big_endian] + + print(f"\nBLOCK {index} :: bytes_len={n_bytes} || n_felts={n_felts}") + print(f"RLP_felt = {rlp_array}") + print(f"bit_big : {[x.bit_length() for x in rlp_array]}") + print(f"RLP_bytes_arr_big = {rlp_bytes_big_endian}") + print(f"RLP_bytes_arr_lil = {rlp_bytes_little_endian}") + print(f"bit_lil : {[x.bit_length() for x in rlp_array_little]}") + + +def print_mmr(memory, mmr_array, mmr_array_len): + mmr_values = [hex(memory[mmr_array + i]) for i in range(mmr_array_len)] + print(f"\nMMR :: mmr_array_len={mmr_array_len}") + print(f"mmr_values = {mmr_values}") From 87649f105dfde073573ecb0cea5fe123af7f7818 Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Mon, 28 Oct 2024 09:07:13 +0100 Subject: [PATCH 2/4] processor rust hints working example --- Cargo.lock | 78 ++++++------ Cargo.toml | 2 +- cairo_vm_hints/Cargo.toml | 4 +- cairo_vm_hints/src/hint_processor/mod.rs | 18 ++- cairo_vm_hints/src/hint_processor/print.rs | 118 ++++++++++++++++++ .../src/hint_processor/{hints.rs => read.rs} | 63 ++++++---- cairo_vm_hints/src/main.rs | 4 +- src/libs/block_header.cairo | 2 +- src/libs/mmr.cairo | 4 +- src/libs/utils.cairo | 1 + .../chunk_processor.cairo | 14 +-- tools/make/prepare_inputs_api.py | 18 +-- tools/py/convert_input.py | 42 +++++++ 13 files changed, 281 insertions(+), 87 deletions(-) create mode 100644 cairo_vm_hints/src/hint_processor/print.rs rename cairo_vm_hints/src/hint_processor/{hints.rs => read.rs} (76%) create mode 100644 tools/py/convert_input.py diff --git a/Cargo.lock b/Cargo.lock index 93137d5..7cbb6c3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -231,45 +231,6 @@ dependencies = [ "zip", ] -[[package]] -name = "cairo_vm_hints" -version = "0.1.0" -source = "git+https://github.com/HerodotusDev/eth_essentials.git?rev=633bd7e23edd2aef9703078efd5a9e72bda95d3c#633bd7e23edd2aef9703078efd5a9e72bda95d3c" -dependencies = [ - "bincode", - "cairo-vm", - "clap", - "hex", - "num-bigint", - "num-traits", - "rand", - "sha3", - "starknet-crypto 0.7.2", - "starknet-types-core", - "thiserror", - "tiny-keccak", -] - -[[package]] -name = "cairo_vm_hints_processor" -version = "0.1.0" -dependencies = [ - "bincode", - "cairo-vm", - "cairo_vm_hints", - "clap", - "hex", - "num-bigint", - "num-traits", - "rand", - "serde_json", - "sha3", - "starknet-crypto 0.7.2", - "starknet-types-core", - "thiserror", - "tiny-keccak", -] - [[package]] name = "cfg-if" version = "1.0.0" @@ -407,6 +368,25 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "eth_essentials_cairo_vm_hints" +version = "0.1.0" +source = "git+https://github.com/HerodotusDev/eth_essentials.git?rev=4faa43104004e459b87645c5c30b82d31b9c6ad5#4faa43104004e459b87645c5c30b82d31b9c6ad5" +dependencies = [ + "bincode", + "cairo-vm", + "clap", + "hex", + "num-bigint", + "num-traits", + "rand", + "sha3", + "starknet-crypto 0.7.2", + "starknet-types-core", + "thiserror", + "tiny-keccak", +] + [[package]] name = "flate2" version = "1.0.34" @@ -474,6 +454,26 @@ dependencies = [ "foldhash", ] +[[package]] +name = "headers_processor_cairo_vm_hints" +version = "0.1.0" +dependencies = [ + "bincode", + "cairo-vm", + "clap", + "eth_essentials_cairo_vm_hints", + "hex", + "num-bigint", + "num-traits", + "rand", + "serde_json", + "sha3", + "starknet-crypto 0.7.2", + "starknet-types-core", + "thiserror", + "tiny-keccak", +] + [[package]] name = "heck" version = "0.5.0" diff --git a/Cargo.toml b/Cargo.toml index 69daccd..05340aa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,5 +17,5 @@ num-traits = "0.2.19" tiny-keccak = { version = "2.0.2", features = ["keccak"] } hex = "0.4.3" starknet-crypto = "0.7.2" -cairo_vm_hints = { git = "https://github.com/HerodotusDev/eth_essentials.git", rev = "633bd7e23edd2aef9703078efd5a9e72bda95d3c" } +eth_essentials_cairo_vm_hints = { git = "https://github.com/HerodotusDev/eth_essentials.git", rev = "4faa43104004e459b87645c5c30b82d31b9c6ad5" } serde_json = "1.0.132" \ No newline at end of file diff --git a/cairo_vm_hints/Cargo.toml b/cairo_vm_hints/Cargo.toml index 5e7c041..99f32af 100644 --- a/cairo_vm_hints/Cargo.toml +++ b/cairo_vm_hints/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "cairo_vm_hints_processor" +name = "headers_processor_cairo_vm_hints" version = "0.1.0" edition = "2021" @@ -16,5 +16,5 @@ num-traits.workspace = true tiny-keccak.workspace = true hex.workspace = true starknet-crypto.workspace = true -cairo_vm_hints.workspace = true +eth_essentials_cairo_vm_hints.workspace = true serde_json.workspace = true \ No newline at end of file diff --git a/cairo_vm_hints/src/hint_processor/mod.rs b/cairo_vm_hints/src/hint_processor/mod.rs index 80c2b6b..bdf97c3 100644 --- a/cairo_vm_hints/src/hint_processor/mod.rs +++ b/cairo_vm_hints/src/hint_processor/mod.rs @@ -17,7 +17,8 @@ use starknet_types_core::felt::Felt; use std::collections::HashMap; use std::{any::Any, rc::Rc}; -pub mod hints; +pub mod print; +pub mod read; #[derive(Default)] pub struct CustomHintProcessor { @@ -37,9 +38,15 @@ impl CustomHintProcessor { constants: &HashMap, ) -> Result<(), HintError> { match hint_data.code.as_str() { - hints::HINT_READ_BLOCK_HEADERS => { + read::HINT_READ_BLOCK_HEADERS => { self.hint_read_block_headers(vm, exec_scope, hint_data, constants) } + read::HINT_READ_INPUT => self.hint_read_input(vm, exec_scope, hint_data, constants), + read::HINT_READ_INPUT_PREV => { + self.hint_read_input_prev(vm, exec_scope, hint_data, constants) + } + print::HINT_PRINT_HASH => self.hint_print_hash(vm, exec_scope, hint_data, constants), + print::HINT_PRINT_FINAL => self.hint_print_final(vm, exec_scope, hint_data, constants), _ => Err(HintError::UnknownHint( hint_data.code.to_string().into_boxed_str(), )), @@ -59,7 +66,12 @@ impl HintProcessorLogic for CustomHintProcessor { .downcast_ref::() .ok_or(HintError::WrongHintData)?; - cairo_vm_hints::hints::run_hint(vm, exec_scopes, hint_data, constants)?; + let res = + eth_essentials_cairo_vm_hints::hints::run_hint(vm, exec_scopes, hint_data, constants); + if !matches!(res, Err(HintError::UnknownHint(_))) { + return res; + } + self.run_hint(vm, exec_scopes, hint_data, constants) } } diff --git a/cairo_vm_hints/src/hint_processor/print.rs b/cairo_vm_hints/src/hint_processor/print.rs new file mode 100644 index 0000000..2a166da --- /dev/null +++ b/cairo_vm_hints/src/hint_processor/print.rs @@ -0,0 +1,118 @@ +use super::CustomHintProcessor; +use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::{ + get_integer_from_var_name, get_relocatable_from_var_name, +}; +use cairo_vm::{ + hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData, + types::exec_scope::ExecutionScopes, + vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, + Felt252, +}; +use std::collections::HashMap; + +pub const HINT_PRINT_HASH: &str = "from tools.py.hints import print_u256\nprint(\"\\n\")\nprint_u256(ids.block_header_hash_little,f\"block_header_keccak_hash_{ids.index}\")\nprint_u256(ids.expected_block_hash,f\"expected_keccak_hash_{ids.index}\")"; +pub const HINT_PRINT_FINAL: &str = "print(\"new root poseidon\", ids.new_mmr_root_poseidon)\nprint(\"new root keccak\", ids.new_mmr_root_keccak.low, ids.new_mmr_root_keccak.high)\nprint(\"new size\", ids.mmr_array_len + ids.mmr_offset)"; + +impl CustomHintProcessor { + pub fn hint_print_hash( + &mut self, + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, + ) -> Result<(), HintError> { + let index = + get_integer_from_var_name("index", vm, &hint_data.ids_data, &hint_data.ap_tracking)?; + + let block_header_hash_little = get_relocatable_from_var_name( + "block_header_hash_little", + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + let expected_block_hash = get_relocatable_from_var_name( + "expected_block_hash", + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + let block_header_hash_little = vm + .get_continuous_range(block_header_hash_little, 2)? + .into_iter() + .map(|v| v.get_int()) + .collect::>>() + .unwrap(); + println!( + "block_header_hash_little_{}, {} {}", + index, block_header_hash_little[0], block_header_hash_little[1] + ); + + let expected_block_hash = vm + .get_continuous_range(expected_block_hash, 2)? + .into_iter() + .map(|v| v.get_int()) + .collect::>>() + .unwrap(); + println!( + "expected_block_hash_{}, {} {}", + index, expected_block_hash[0], expected_block_hash[1] + ); + + Ok(()) + } + + pub fn hint_print_final( + &mut self, + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, + ) -> Result<(), HintError> { + let new_mmr_root_poseidon = get_integer_from_var_name( + "new_mmr_root_poseidon", + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + let new_mmr_root_keccak = get_relocatable_from_var_name( + "new_mmr_root_keccak", + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + let mmr_array_len = get_integer_from_var_name( + "mmr_array_len", + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + let mmr_offset = get_integer_from_var_name( + "mmr_offset", + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + println!("new root poseidon: {}", new_mmr_root_poseidon); + + let new_mmr_root_keccak = vm + .get_continuous_range(new_mmr_root_keccak, 2)? + .into_iter() + .map(|v| v.get_int()) + .collect::>>() + .unwrap(); + println!( + "new root keccak: {} {}", + new_mmr_root_keccak[0], new_mmr_root_keccak[1] + ); + + println!("new size: {}", mmr_array_len + mmr_offset); + + Ok(()) + } +} diff --git a/cairo_vm_hints/src/hint_processor/hints.rs b/cairo_vm_hints/src/hint_processor/read.rs similarity index 76% rename from cairo_vm_hints/src/hint_processor/hints.rs rename to cairo_vm_hints/src/hint_processor/read.rs index 1587bc8..34974e3 100644 --- a/cairo_vm_hints/src/hint_processor/hints.rs +++ b/cairo_vm_hints/src/hint_processor/read.rs @@ -1,3 +1,4 @@ +use super::CustomHintProcessor; use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::get_ptr_from_var_name; use cairo_vm::types::relocatable::MaybeRelocatable; use cairo_vm::{ @@ -6,13 +7,11 @@ use cairo_vm::{ vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, Felt252, }; -use cairo_vm_hints::utils; +use eth_essentials_cairo_vm_hints::utils; use std::collections::HashMap; -use super::CustomHintProcessor; - pub const HINT_READ_INPUT: &str = "ids.from_block_number_high=program_input['from_block_number_high']\nids.to_block_number_low=program_input['to_block_number_low']\nids.mmr_offset=program_input['mmr_last_len'] \nids.mmr_last_root_poseidon=program_input['mmr_last_root_poseidon']\nids.mmr_last_root_keccak.low=program_input['mmr_last_root_keccak_low']\nids.mmr_last_root_keccak.high=program_input['mmr_last_root_keccak_high']\nids.block_n_plus_one_parent_hash_little.low = program_input['block_n_plus_one_parent_hash_little_low']\nids.block_n_plus_one_parent_hash_little.high = program_input['block_n_plus_one_parent_hash_little_high']"; -pub const HINT_READ_INPUT_PREV: &str = "segments.write_arg(ids.previous_peaks_values_poseidon, program_input['poseidon_mmr_last_peaks']) \nwrite_uint256_array(ids.previous_peaks_values_keccak, program_input['keccak_mmr_last_peaks'])"; +pub const HINT_READ_INPUT_PREV: &str = "from tools.py.hints import write_uint256_array\nsegments.write_arg(ids.previous_peaks_values_poseidon, program_input['poseidon_mmr_last_peaks']) \nwrite_uint256_array(memory, ids.previous_peaks_values_keccak, program_input['keccak_mmr_last_peaks'])"; pub const HINT_READ_BLOCK_HEADERS: &str = "block_headers_array = program_input['block_headers_array']\nbytes_len_array = program_input['bytes_len_array']\nsegments.write_arg(ids.block_headers_array, block_headers_array)\nsegments.write_arg(ids.block_headers_array_bytes_len, bytes_len_array)"; impl CustomHintProcessor { @@ -24,27 +23,30 @@ impl CustomHintProcessor { _constants: &HashMap, ) -> Result<(), HintError> { let from_block_number_high: Felt252 = - serde_json::from_value(self.private_inputs["from_block_number_high"].clone()).unwrap(); + serde_json::from_value(self.private_inputs["from_block_number_high"].clone()) + .unwrap_or_default(); let to_block_number_low: Felt252 = - serde_json::from_value(self.private_inputs["to_block_number_low"].clone()).unwrap(); + serde_json::from_value(self.private_inputs["to_block_number_low"].clone()) + .unwrap_or_default(); let mmr_offset: Felt252 = - serde_json::from_value(self.private_inputs["mmr_offset"].clone()).unwrap(); + serde_json::from_value(self.private_inputs["mmr_last_len"].clone()).unwrap_or_default(); let mmr_last_root_poseidon: Felt252 = - serde_json::from_value(self.private_inputs["mmr_last_root_poseidon"].clone()).unwrap(); + serde_json::from_value(self.private_inputs["mmr_last_root_poseidon"].clone()) + .unwrap_or_default(); let mmr_last_root_keccak_low: Felt252 = serde_json::from_value(self.private_inputs["mmr_last_root_keccak_low"].clone()) - .unwrap(); + .unwrap_or_default(); let mmr_last_root_keccak_high: Felt252 = serde_json::from_value(self.private_inputs["mmr_last_root_keccak_high"].clone()) - .unwrap(); + .unwrap_or_default(); let block_n_plus_one_parent_hash_little_low: Felt252 = serde_json::from_value( self.private_inputs["block_n_plus_one_parent_hash_little_low"].clone(), ) - .unwrap(); + .unwrap_or_default(); let block_n_plus_one_parent_hash_little_high: Felt252 = serde_json::from_value( self.private_inputs["block_n_plus_one_parent_hash_little_high"].clone(), ) - .unwrap(); + .unwrap_or_default(); utils::write_value( "from_block_number_high", @@ -128,11 +130,17 @@ impl CustomHintProcessor { &hint_data.ap_tracking, )?; - vm.segments - .write_arg(previous_peaks_values_poseidon_ptr, &poseidon_mmr_last_peaks)?; + for (j, value) in poseidon_mmr_last_peaks + .into_iter() + .map(MaybeRelocatable::Int) + .enumerate() + { + vm.insert_value((previous_peaks_values_poseidon_ptr + j)?, &value)?; + } - vm.segments - .write_arg(previous_peaks_values_keccak_ptr, &keccak_mmr_last_peaks)?; + for (j, array) in keccak_mmr_last_peaks.into_iter().flatten().enumerate() { + vm.insert_value((previous_peaks_values_keccak_ptr + j)?, array)?; + } Ok(()) } @@ -144,10 +152,10 @@ impl CustomHintProcessor { hint_data: &HintProcessorData, _constants: &HashMap, ) -> Result<(), HintError> { - let block_headers_array: Vec> = + let block_headers_array: Vec> = serde_json::from_value(self.private_inputs["block_headers_array"].clone()).unwrap(); - let bytes_len_array: Vec = + let bytes_len_array: Vec = serde_json::from_value(self.private_inputs["bytes_len_array"].clone()).unwrap(); let block_headers_array_ptr = get_ptr_from_var_name( @@ -164,10 +172,21 @@ impl CustomHintProcessor { &hint_data.ap_tracking, )?; - vm.segments - .write_arg(block_headers_array_ptr, &block_headers_array)?; - vm.segments - .write_arg(block_headers_array_bytes_len_ptr, &bytes_len_array)?; + for (j, array) in block_headers_array.into_iter().enumerate() { + let segment = vm.segments.add(); + for (k, value) in array.into_iter().map(MaybeRelocatable::Int).enumerate() { + vm.insert_value((segment + k)?, &value)?; + } + vm.insert_value((block_headers_array_ptr + j)?, segment)?; + } + + for (j, value) in bytes_len_array + .into_iter() + .map(MaybeRelocatable::Int) + .enumerate() + { + vm.insert_value((block_headers_array_bytes_len_ptr + j)?, &value)?; + } Ok(()) } diff --git a/cairo_vm_hints/src/main.rs b/cairo_vm_hints/src/main.rs index 414f74d..fef6502 100644 --- a/cairo_vm_hints/src/main.rs +++ b/cairo_vm_hints/src/main.rs @@ -1,5 +1,7 @@ #![deny(warnings)] #![forbid(unsafe_code)] +pub mod hint_processor; + use bincode::enc::write::Writer; use cairo_vm::air_public_input::PublicInputError; use cairo_vm::cairo_run::{self, EncodeTraceError}; @@ -15,8 +17,8 @@ use cairo_vm::vm::errors::vm_errors::VirtualMachineError; use cairo_vm::vm::runners::cairo_pie::CairoPie; // #[cfg(feature = "with_tracer")] // use cairo_vm::vm::runners::cairo_runner::CairoRunner; +use crate::hint_processor::ExtendedHintProcessor; use cairo_vm::vm::runners::cairo_runner::RunResources; -use cairo_vm_hints_processor::hint_processor::ExtendedHintProcessor; // #[cfg(feature = "with_tracer")] // use cairo_vm_tracer::error::trace_data_errors::TraceDataError; // #[cfg(feature = "with_tracer")] diff --git a/src/libs/block_header.cairo b/src/libs/block_header.cairo index 0973cbb..a610b1f 100644 --- a/src/libs/block_header.cairo +++ b/src/libs/block_header.cairo @@ -84,7 +84,7 @@ func extract_parent_hash_little{range_check_ptr}(rlp: felt*) -> (res: Uint256) { // // Reference: https://ethereum.org/en/developers/docs/data-structures-and-encoding/rlp/#definition func get_bigint_byte_size{range_check_ptr}(byte: felt) -> felt { - %{ memory[ap]=1 if ids.byte<=127 else 0 %} + %{ memory[ap] = 1 if ids.byte <= 127 else 0 %} ap += 1; let is_single_byte = [ap - 1]; diff --git a/src/libs/mmr.cairo b/src/libs/mmr.cairo index be8458d..a640e58 100644 --- a/src/libs/mmr.cairo +++ b/src/libs/mmr.cairo @@ -233,8 +233,8 @@ func left_child_jump_until_inside_mmr{range_check_ptr, pow2_array: felt*, mmr_le ) -> felt { alloc_locals; local in_mmr; - %{ ids.in_mmr = 1 if ids.left_child<=ids.mmr_len else 0 %} - + %{ ids.in_mmr = 1 if ids.left_child <= ids.mmr_len else 0 %} + if (in_mmr != 0) { // Ensure left_child <= mmr_len assert [range_check_ptr] = mmr_len - left_child; diff --git a/src/libs/utils.cairo b/src/libs/utils.cairo index d153764..d8a1f51 100644 --- a/src/libs/utils.cairo +++ b/src/libs/utils.cairo @@ -5,6 +5,7 @@ from starkware.cairo.common.alloc import alloc const DIV_32 = 2 ** 32; const DIV_32_MINUS_1 = DIV_32 - 1; +const PRIME = 3618502788666131213697322783095070105623107215331596699973092056135872020481; // Returns the number of bits in x. // Implicits arguments: diff --git a/src/single_chunk_processor/chunk_processor.cairo b/src/single_chunk_processor/chunk_processor.cairo index 681063b..a73ce7c 100644 --- a/src/single_chunk_processor/chunk_processor.cairo +++ b/src/single_chunk_processor/chunk_processor.cairo @@ -69,7 +69,7 @@ func verify_block_headers_and_hash_them{ assert 0 = block_header_hash_little.low - expected_block_hash.low; assert 0 = block_header_hash_little.high - expected_block_hash.high; - %{ + %{ from tools.py.hints import print_u256 print("\n") print_u256(ids.block_header_hash_little,f"block_header_keccak_hash_{ids.index}") @@ -351,11 +351,11 @@ func main{ // Common variable for both MMR : let mmr_array_len = 0; - %{ - #print_block_header(ids.block_headers_array, ids.bytes_len_array, ids.n) - #print_block_header(ids.block_headers_array, ids.bytes_len_array, ids.n-1) - #print_block_header(ids.block_headers_array, ids.bytes_len_array, 0) - %} + // %{ + // #print_block_header(ids.block_headers_array, ids.bytes_len_array, ids.n) + // #print_block_header(ids.block_headers_array, ids.bytes_len_array, ids.n-1) + // #print_block_header(ids.block_headers_array, ids.bytes_len_array, 0) + // %} // ----------------------------------------------------- // ----------------------------------------------------- @@ -396,7 +396,7 @@ func main{ let (new_mmr_root_poseidon: felt, new_mmr_root_keccak: Uint256) = get_roots(); } - %{ + %{ print("new root poseidon", ids.new_mmr_root_poseidon) print("new root keccak", ids.new_mmr_root_keccak.low, ids.new_mmr_root_keccak.high) print("new size", ids.mmr_array_len + ids.mmr_offset) diff --git a/tools/make/prepare_inputs_api.py b/tools/make/prepare_inputs_api.py index 734b48e..7e69239 100755 --- a/tools/make/prepare_inputs_api.py +++ b/tools/make/prepare_inputs_api.py @@ -388,16 +388,16 @@ def prepare_full_chain_inputs( if __name__ == "__main__": output = prepare_full_chain_inputs( - from_block_number_high=20, + from_block_number_high=19999, to_block_number_low=0, - batch_size=5, + batch_size=20000, dynamic=False, ) - # Prepare _inputs.json and pre-compute _outputs.json using the last peaks, size and roots from the previous run: - prepare_full_chain_inputs( - from_block_number_high=30, - to_block_number_low=21, - batch_size=5, - initial_params=output, - ) + # # Prepare _inputs.json and pre-compute _outputs.json using the last peaks, size and roots from the previous run: + # prepare_full_chain_inputs( + # from_block_number_high=30, + # to_block_number_low=21, + # batch_size=5, + # initial_params=output, + # ) diff --git a/tools/py/convert_input.py b/tools/py/convert_input.py new file mode 100644 index 0000000..9194177 --- /dev/null +++ b/tools/py/convert_input.py @@ -0,0 +1,42 @@ +import json +import argparse + +def convert_numbers_to_hex_strings(data): + """ + Recursively converts integers in data to hexadecimal strings. + Handles dictionaries, lists, integers, floats, and other types. + """ + if isinstance(data, dict): + return {key: convert_numbers_to_hex_strings(value) for key, value in data.items()} + elif isinstance(data, list): + return [convert_numbers_to_hex_strings(item) for item in data] + elif isinstance(data, int): + return hex(data) + elif isinstance(data, float): + return str(data) + else: + return data + +def main(input_file, output_file): + # Load JSON data from input file + with open(input_file, "r") as f: + json_data = json.load(f) + + # Convert integers in JSON to hexadecimal strings + converted_data = convert_numbers_to_hex_strings(json_data) + + # Save the converted JSON data to output file + with open(output_file, "w") as f: + json.dump(converted_data, f, indent=4) + + print(f"Converted numbers to hexadecimal strings in '{output_file}'") + +if __name__ == "__main__": + # Set up argument parsing for input and output file paths + parser = argparse.ArgumentParser(description="Convert integers in JSON to hexadecimal strings.") + parser.add_argument("input_file", help="Path to the input JSON file") + parser.add_argument("output_file", help="Path to save the output JSON file") + + # Parse arguments and run the main function + args = parser.parse_args() + main(args.input_file, args.output_file) From b370dd1caae3074b6effc668583ad797c0c25294 Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Mon, 28 Oct 2024 09:09:41 +0100 Subject: [PATCH 3/4] format python --- tools/make/prepare_inputs_api.py | 8 -- tools/py/block_header.py | 227 ++++++++++++++++--------------- tools/py/compute_fact.py | 54 ++++---- tools/py/convert_input.py | 19 ++- tools/py/fetch_block_headers.py | 6 +- tools/py/hints.py | 3 +- tools/py/utils.py | 1 + 7 files changed, 164 insertions(+), 154 deletions(-) diff --git a/tools/make/prepare_inputs_api.py b/tools/make/prepare_inputs_api.py index 7e69239..477fc6b 100755 --- a/tools/make/prepare_inputs_api.py +++ b/tools/make/prepare_inputs_api.py @@ -393,11 +393,3 @@ def prepare_full_chain_inputs( batch_size=20000, dynamic=False, ) - - # # Prepare _inputs.json and pre-compute _outputs.json using the last peaks, size and roots from the previous run: - # prepare_full_chain_inputs( - # from_block_number_high=30, - # to_block_number_low=21, - # batch_size=5, - # initial_params=output, - # ) diff --git a/tools/py/block_header.py b/tools/py/block_header.py index 7e44164..a99b44a 100644 --- a/tools/py/block_header.py +++ b/tools/py/block_header.py @@ -16,146 +16,151 @@ int256 = BigEndianInt(256) trie_root = Binary.fixed_length(32, allow_empty=True) + class BlockHeader(Serializable): fields = ( - ('parentHash', hash32), - ('unclesHash', hash32), - ('coinbase', address), - ('stateRoot', trie_root), - ('transactionsRoot', trie_root), - ('receiptsRoot', trie_root), - ('logsBloom', int256), - ('difficulty', big_endian_int), - ('number', big_endian_int), - ('gasLimit', big_endian_int), - ('gasUsed', big_endian_int), - ('timestamp', big_endian_int), - ('extraData', binary), - ('mixHash', binary), - ('nonce', Binary(8, allow_empty=True)), + ("parentHash", hash32), + ("unclesHash", hash32), + ("coinbase", address), + ("stateRoot", trie_root), + ("transactionsRoot", trie_root), + ("receiptsRoot", trie_root), + ("logsBloom", int256), + ("difficulty", big_endian_int), + ("number", big_endian_int), + ("gasLimit", big_endian_int), + ("gasUsed", big_endian_int), + ("timestamp", big_endian_int), + ("extraData", binary), + ("mixHash", binary), + ("nonce", Binary(8, allow_empty=True)), ) def hash(self) -> HexBytes: _rlp = encode(self) return Web3.keccak(_rlp) - + def raw_rlp(self) -> bytes: return encode(self) - + + class BlockHeaderEIP1559(Serializable): fields = ( - ('parentHash', hash32), - ('unclesHash', hash32), - ('coinbase', address), - ('stateRoot', trie_root), - ('transactionsRoot', trie_root), - ('receiptsRoot', trie_root), - ('logsBloom', int256), - ('difficulty', big_endian_int), - ('number', big_endian_int), - ('gasLimit', big_endian_int), - ('gasUsed', big_endian_int), - ('timestamp', big_endian_int), - ('extraData', binary), - ('mixHash', binary), - ('nonce', Binary(8, allow_empty=True)), - ('baseFeePerGas', big_endian_int), - + ("parentHash", hash32), + ("unclesHash", hash32), + ("coinbase", address), + ("stateRoot", trie_root), + ("transactionsRoot", trie_root), + ("receiptsRoot", trie_root), + ("logsBloom", int256), + ("difficulty", big_endian_int), + ("number", big_endian_int), + ("gasLimit", big_endian_int), + ("gasUsed", big_endian_int), + ("timestamp", big_endian_int), + ("extraData", binary), + ("mixHash", binary), + ("nonce", Binary(8, allow_empty=True)), + ("baseFeePerGas", big_endian_int), ) + def hash(self) -> HexBytes: _rlp = encode(self) return Web3.keccak(_rlp) - + def raw_rlp(self) -> bytes: return encode(self) + class BlockHeaderShangai(Serializable): fields = ( - ('parentHash', hash32), - ('unclesHash', hash32), - ('coinbase', address), - ('stateRoot', trie_root), - ('transactionsRoot', trie_root), - ('receiptsRoot', trie_root), - ('logsBloom', int256), - ('difficulty', big_endian_int), - ('number', big_endian_int), - ('gasLimit', big_endian_int), - ('gasUsed', big_endian_int), - ('timestamp', big_endian_int), - ('extraData', binary), - ('mixHash', binary), - ('nonce', Binary(8, allow_empty=True)), - ('baseFeePerGas', big_endian_int), - ('withdrawalsRoot', trie_root) - + ("parentHash", hash32), + ("unclesHash", hash32), + ("coinbase", address), + ("stateRoot", trie_root), + ("transactionsRoot", trie_root), + ("receiptsRoot", trie_root), + ("logsBloom", int256), + ("difficulty", big_endian_int), + ("number", big_endian_int), + ("gasLimit", big_endian_int), + ("gasUsed", big_endian_int), + ("timestamp", big_endian_int), + ("extraData", binary), + ("mixHash", binary), + ("nonce", Binary(8, allow_empty=True)), + ("baseFeePerGas", big_endian_int), + ("withdrawalsRoot", trie_root), ) + def hash(self) -> HexBytes: _rlp = encode(self) return Web3.keccak(_rlp) - + def raw_rlp(self) -> bytes: return encode(self) - -def build_block_header(block: BlockData) -> Union[BlockHeader, BlockHeaderEIP1559, BlockHeaderShangai]: - if 'withdrawalsRoot' in block.keys(): + +def build_block_header( + block: BlockData, +) -> Union[BlockHeader, BlockHeaderEIP1559, BlockHeaderShangai]: + + if "withdrawalsRoot" in block.keys(): header = BlockHeaderShangai( - HexBytes(block["parentHash"]), - HexBytes(block["sha3Uncles"]), - bytearray.fromhex(block['miner'][2:]), - HexBytes(block["stateRoot"]), - HexBytes(block['transactionsRoot']), - HexBytes(block["receiptsRoot"]), - int.from_bytes(HexBytes(block["logsBloom"]), 'big'), - int(block["difficulty"],16), - int(block["number"], 16), - int(block["gasLimit"],16), - int(block["gasUsed"],16), - int(block["timestamp"],16), - HexBytes(block["extraData"]), - HexBytes(block["mixHash"]), - HexBytes(block["nonce"]), - int(block["baseFeePerGas"],16), - HexBytes(block["withdrawalsRoot"]) - ) - elif 'baseFeePerGas' in block.keys(): + HexBytes(block["parentHash"]), + HexBytes(block["sha3Uncles"]), + bytearray.fromhex(block["miner"][2:]), + HexBytes(block["stateRoot"]), + HexBytes(block["transactionsRoot"]), + HexBytes(block["receiptsRoot"]), + int.from_bytes(HexBytes(block["logsBloom"]), "big"), + int(block["difficulty"], 16), + int(block["number"], 16), + int(block["gasLimit"], 16), + int(block["gasUsed"], 16), + int(block["timestamp"], 16), + HexBytes(block["extraData"]), + HexBytes(block["mixHash"]), + HexBytes(block["nonce"]), + int(block["baseFeePerGas"], 16), + HexBytes(block["withdrawalsRoot"]), + ) + elif "baseFeePerGas" in block.keys(): header = BlockHeaderEIP1559( - HexBytes(block["parentHash"]), - HexBytes(block["sha3Uncles"]), - bytearray.fromhex(block['miner'][2:]), - HexBytes(block["stateRoot"]), - HexBytes(block['transactionsRoot']), - HexBytes(block["receiptsRoot"]), - int.from_bytes(HexBytes(block["logsBloom"]), 'big'), - int(block["difficulty"],16), - int(block["number"], 16), - int(block["gasLimit"],16), - int(block["gasUsed"],16), - int(block["timestamp"],16), - HexBytes(block["extraData"]), - HexBytes(block["mixHash"]), - HexBytes(block["nonce"]), - int(block["baseFeePerGas"],16), - ) - + HexBytes(block["parentHash"]), + HexBytes(block["sha3Uncles"]), + bytearray.fromhex(block["miner"][2:]), + HexBytes(block["stateRoot"]), + HexBytes(block["transactionsRoot"]), + HexBytes(block["receiptsRoot"]), + int.from_bytes(HexBytes(block["logsBloom"]), "big"), + int(block["difficulty"], 16), + int(block["number"], 16), + int(block["gasLimit"], 16), + int(block["gasUsed"], 16), + int(block["timestamp"], 16), + HexBytes(block["extraData"]), + HexBytes(block["mixHash"]), + HexBytes(block["nonce"]), + int(block["baseFeePerGas"], 16), + ) + else: header = BlockHeader( - HexBytes(block["parentHash"]), - HexBytes(block["sha3Uncles"]), - bytearray.fromhex(block['miner'][2:]), - HexBytes(block["stateRoot"]), - HexBytes(block['transactionsRoot']), - HexBytes(block["receiptsRoot"]), - int.from_bytes(HexBytes(block["logsBloom"]), 'big'), - int(block["difficulty"],16), - int(block["number"], 16), - int(block["gasLimit"],16), - int(block["gasUsed"],16), - int(block["timestamp"],16), - HexBytes(block["extraData"]), - HexBytes(block["mixHash"]), - HexBytes(block["nonce"]), - ) + HexBytes(block["parentHash"]), + HexBytes(block["sha3Uncles"]), + bytearray.fromhex(block["miner"][2:]), + HexBytes(block["stateRoot"]), + HexBytes(block["transactionsRoot"]), + HexBytes(block["receiptsRoot"]), + int.from_bytes(HexBytes(block["logsBloom"]), "big"), + int(block["difficulty"], 16), + int(block["number"], 16), + int(block["gasLimit"], 16), + int(block["gasUsed"], 16), + int(block["timestamp"], 16), + HexBytes(block["extraData"]), + HexBytes(block["mixHash"]), + HexBytes(block["nonce"]), + ) return header - \ No newline at end of file diff --git a/tools/py/compute_fact.py b/tools/py/compute_fact.py index 4a39f95..79d54fb 100644 --- a/tools/py/compute_fact.py +++ b/tools/py/compute_fact.py @@ -1,28 +1,33 @@ """ Simple script to show how to compute the fact for a given program hash and program output. """ + from web3 import Web3 from typing import List + # Pedersen hash of the compiled program -program_hash = 0x21876b34efae7a9a59580c4fb0bfc7971aecebce6669a475171fe0423c0a784 +program_hash = 0x21876B34EFAE7A9A59580C4FB0BFC7971AECEBCE6669A475171FE0423C0A784 + # output of field elements from the cairo program run -def get_program_output_values_from_output_dict(output:dict) -> List[int]: - program_output = [output['from_block_number_high'], - output['to_block_number_low'], - output['block_n_plus_one_parent_hash_low'], - output['block_n_plus_one_parent_hash_high'], - output['block_n_minus_r_plus_one_parent_hash_low'], - output['block_n_minus_r_plus_one_parent_hash_high'], - output['mmr_last_root_poseidon'], - output['mmr_last_root_keccak_low'], - output['mmr_last_root_keccak_high'], - output['mmr_last_len'], - output['new_mmr_root_poseidon'], - output['new_mmr_root_keccak_low'], - output['new_mmr_root_keccak_high'], - output['new_mmr_len']] - return program_output +def get_program_output_values_from_output_dict(output: dict) -> List[int]: + program_output = [ + output["from_block_number_high"], + output["to_block_number_low"], + output["block_n_plus_one_parent_hash_low"], + output["block_n_plus_one_parent_hash_high"], + output["block_n_minus_r_plus_one_parent_hash_low"], + output["block_n_minus_r_plus_one_parent_hash_high"], + output["mmr_last_root_poseidon"], + output["mmr_last_root_keccak_low"], + output["mmr_last_root_keccak_high"], + output["mmr_last_len"], + output["new_mmr_root_poseidon"], + output["new_mmr_root_keccak_low"], + output["new_mmr_root_keccak_high"], + output["new_mmr_len"], + ] + return program_output sample_output = { @@ -39,20 +44,19 @@ def get_program_output_values_from_output_dict(output:dict) -> List[int]: "new_mmr_root_poseidon": 252551093926361284205375255497947755050313027176556264268816177711092997281, "new_mmr_root_keccak_low": 1282909371342134768584297556671282863, "new_mmr_root_keccak_high": 320481516134505083105287001274104545683, - "new_mmr_len": 19 + "new_mmr_len": 19, } -def compute_fact(program_hash:int, program_output:List[int]): +def compute_fact(program_hash: int, program_output: List[int]): kecOutput = Web3.solidityKeccak(["uint256[]"], [program_output]) fact = Web3.solidityKeccak(["uint256", "bytes32"], [program_hash, kecOutput]) return fact.hex() -if __name__ == '__main__': - fact = compute_fact(program_hash, get_program_output_values_from_output_dict(sample_output)) - - print(fact) - - +if __name__ == "__main__": + fact = compute_fact( + program_hash, get_program_output_values_from_output_dict(sample_output) + ) + print(fact) diff --git a/tools/py/convert_input.py b/tools/py/convert_input.py index 9194177..1c43cb2 100644 --- a/tools/py/convert_input.py +++ b/tools/py/convert_input.py @@ -1,13 +1,16 @@ import json import argparse + def convert_numbers_to_hex_strings(data): """ Recursively converts integers in data to hexadecimal strings. Handles dictionaries, lists, integers, floats, and other types. """ if isinstance(data, dict): - return {key: convert_numbers_to_hex_strings(value) for key, value in data.items()} + return { + key: convert_numbers_to_hex_strings(value) for key, value in data.items() + } elif isinstance(data, list): return [convert_numbers_to_hex_strings(item) for item in data] elif isinstance(data, int): @@ -17,26 +20,30 @@ def convert_numbers_to_hex_strings(data): else: return data + def main(input_file, output_file): # Load JSON data from input file with open(input_file, "r") as f: json_data = json.load(f) - + # Convert integers in JSON to hexadecimal strings converted_data = convert_numbers_to_hex_strings(json_data) - + # Save the converted JSON data to output file with open(output_file, "w") as f: json.dump(converted_data, f, indent=4) - + print(f"Converted numbers to hexadecimal strings in '{output_file}'") + if __name__ == "__main__": # Set up argument parsing for input and output file paths - parser = argparse.ArgumentParser(description="Convert integers in JSON to hexadecimal strings.") + parser = argparse.ArgumentParser( + description="Convert integers in JSON to hexadecimal strings." + ) parser.add_argument("input_file", help="Path to the input JSON file") parser.add_argument("output_file", help="Path to save the output JSON file") - + # Parse arguments and run the main function args = parser.parse_args() main(args.input_file, args.output_file) diff --git a/tools/py/fetch_block_headers.py b/tools/py/fetch_block_headers.py index b24606b..c8c378f 100644 --- a/tools/py/fetch_block_headers.py +++ b/tools/py/fetch_block_headers.py @@ -60,9 +60,9 @@ def fetch_blocks_from_rpc_no_async( results = rpc_request(rpc_url, requests) # print(results) for result in results: - block_header: Union[ - BlockHeader, BlockHeaderEIP1559, BlockHeaderShangai - ] = build_block_header(result["result"]) + block_header: Union[BlockHeader, BlockHeaderEIP1559, BlockHeaderShangai] = ( + build_block_header(result["result"]) + ) all_results.append(block_header) time.sleep(delay) # Add delay diff --git a/tools/py/hints.py b/tools/py/hints.py index 939361f..9eec2ea 100644 --- a/tools/py/hints.py +++ b/tools/py/hints.py @@ -4,6 +4,7 @@ def write_word_to_memory(word: int, n: int, memory, ap) -> None: for i in range(n): memory[ap + i] = word_bytes[i] + def print_u256(x, name): value = x.low + (x.high << 128) print(f"{name} = {hex(value)}") @@ -23,7 +24,7 @@ def print_block_header(memory, block_headers_array, bytes_len_array, index): rlp_array = [memory[rlp_ptr + i] for i in range(n_felts)] rlp_bytes_big_endian = [x.to_bytes(8, "big") for x in rlp_array] rlp_bytes_little_endian = [x.to_bytes(8, "little") for x in rlp_array] - rlp_array_little = [int.from_bytes(b, 'little') for b in rlp_bytes_big_endian] + rlp_array_little = [int.from_bytes(b, "little") for b in rlp_bytes_big_endian] print(f"\nBLOCK {index} :: bytes_len={n_bytes} || n_felts={n_felts}") print(f"RLP_felt = {rlp_array}") diff --git a/tools/py/utils.py b/tools/py/utils.py index bf35e36..ef72917 100644 --- a/tools/py/utils.py +++ b/tools/py/utils.py @@ -1,4 +1,5 @@ """Utility functions.""" + import json import os import shutil From 8cac21a1225eceba4a56712840b438d5f05c5ce4 Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Tue, 29 Oct 2024 07:56:33 +0100 Subject: [PATCH 4/4] print hints separated --- .../src/hint_processor/{read.rs => input.rs} | 12 +- cairo_vm_hints/src/hint_processor/mod.rs | 23 ++-- cairo_vm_hints/src/hint_processor/print.rs | 118 ---------------- cairo_vm_hints/src/hints/mod.rs | 28 ++++ cairo_vm_hints/src/hints/print.rs | 126 ++++++++++++++++++ cairo_vm_hints/src/lib.rs | 2 + cairo_vm_hints/src/main.rs | 2 +- tools/make/prepare_inputs_api.py | 4 +- 8 files changed, 177 insertions(+), 138 deletions(-) rename cairo_vm_hints/src/hint_processor/{read.rs => input.rs} (83%) delete mode 100644 cairo_vm_hints/src/hint_processor/print.rs create mode 100644 cairo_vm_hints/src/hints/mod.rs create mode 100644 cairo_vm_hints/src/hints/print.rs diff --git a/cairo_vm_hints/src/hint_processor/read.rs b/cairo_vm_hints/src/hint_processor/input.rs similarity index 83% rename from cairo_vm_hints/src/hint_processor/read.rs rename to cairo_vm_hints/src/hint_processor/input.rs index 34974e3..2d84cad 100644 --- a/cairo_vm_hints/src/hint_processor/read.rs +++ b/cairo_vm_hints/src/hint_processor/input.rs @@ -10,12 +10,12 @@ use cairo_vm::{ use eth_essentials_cairo_vm_hints::utils; use std::collections::HashMap; -pub const HINT_READ_INPUT: &str = "ids.from_block_number_high=program_input['from_block_number_high']\nids.to_block_number_low=program_input['to_block_number_low']\nids.mmr_offset=program_input['mmr_last_len'] \nids.mmr_last_root_poseidon=program_input['mmr_last_root_poseidon']\nids.mmr_last_root_keccak.low=program_input['mmr_last_root_keccak_low']\nids.mmr_last_root_keccak.high=program_input['mmr_last_root_keccak_high']\nids.block_n_plus_one_parent_hash_little.low = program_input['block_n_plus_one_parent_hash_little_low']\nids.block_n_plus_one_parent_hash_little.high = program_input['block_n_plus_one_parent_hash_little_high']"; -pub const HINT_READ_INPUT_PREV: &str = "from tools.py.hints import write_uint256_array\nsegments.write_arg(ids.previous_peaks_values_poseidon, program_input['poseidon_mmr_last_peaks']) \nwrite_uint256_array(memory, ids.previous_peaks_values_keccak, program_input['keccak_mmr_last_peaks'])"; -pub const HINT_READ_BLOCK_HEADERS: &str = "block_headers_array = program_input['block_headers_array']\nbytes_len_array = program_input['bytes_len_array']\nsegments.write_arg(ids.block_headers_array, block_headers_array)\nsegments.write_arg(ids.block_headers_array_bytes_len, bytes_len_array)"; +pub const HINT_INPUT: &str = "ids.from_block_number_high=program_input['from_block_number_high']\nids.to_block_number_low=program_input['to_block_number_low']\nids.mmr_offset=program_input['mmr_last_len'] \nids.mmr_last_root_poseidon=program_input['mmr_last_root_poseidon']\nids.mmr_last_root_keccak.low=program_input['mmr_last_root_keccak_low']\nids.mmr_last_root_keccak.high=program_input['mmr_last_root_keccak_high']\nids.block_n_plus_one_parent_hash_little.low = program_input['block_n_plus_one_parent_hash_little_low']\nids.block_n_plus_one_parent_hash_little.high = program_input['block_n_plus_one_parent_hash_little_high']"; +pub const HINT_INPUT_PREV: &str = "from tools.py.hints import write_uint256_array\nsegments.write_arg(ids.previous_peaks_values_poseidon, program_input['poseidon_mmr_last_peaks']) \nwrite_uint256_array(memory, ids.previous_peaks_values_keccak, program_input['keccak_mmr_last_peaks'])"; +pub const HINT_INPUT_BLOCK_HEADERS: &str = "block_headers_array = program_input['block_headers_array']\nbytes_len_array = program_input['bytes_len_array']\nsegments.write_arg(ids.block_headers_array, block_headers_array)\nsegments.write_arg(ids.block_headers_array_bytes_len, bytes_len_array)"; impl CustomHintProcessor { - pub fn hint_read_input( + pub fn hint_input( &mut self, vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, @@ -103,7 +103,7 @@ impl CustomHintProcessor { Ok(()) } - pub fn hint_read_input_prev( + pub fn hint_input_prev( &mut self, vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, @@ -145,7 +145,7 @@ impl CustomHintProcessor { Ok(()) } - pub fn hint_read_block_headers( + pub fn hint_input_block_headers( &mut self, vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, diff --git a/cairo_vm_hints/src/hint_processor/mod.rs b/cairo_vm_hints/src/hint_processor/mod.rs index bdf97c3..ebfdba7 100644 --- a/cairo_vm_hints/src/hint_processor/mod.rs +++ b/cairo_vm_hints/src/hint_processor/mod.rs @@ -1,3 +1,6 @@ +pub mod input; + +use crate::hints; use cairo_vm::{ hint_processor::{ builtin_hint_processor::builtin_hint_processor_definition::{ @@ -17,9 +20,6 @@ use starknet_types_core::felt::Felt; use std::collections::HashMap; use std::{any::Any, rc::Rc}; -pub mod print; -pub mod read; - #[derive(Default)] pub struct CustomHintProcessor { pub private_inputs: serde_json::Value, @@ -38,15 +38,11 @@ impl CustomHintProcessor { constants: &HashMap, ) -> Result<(), HintError> { match hint_data.code.as_str() { - read::HINT_READ_BLOCK_HEADERS => { - self.hint_read_block_headers(vm, exec_scope, hint_data, constants) + input::HINT_INPUT_BLOCK_HEADERS => { + self.hint_input_block_headers(vm, exec_scope, hint_data, constants) } - read::HINT_READ_INPUT => self.hint_read_input(vm, exec_scope, hint_data, constants), - read::HINT_READ_INPUT_PREV => { - self.hint_read_input_prev(vm, exec_scope, hint_data, constants) - } - print::HINT_PRINT_HASH => self.hint_print_hash(vm, exec_scope, hint_data, constants), - print::HINT_PRINT_FINAL => self.hint_print_final(vm, exec_scope, hint_data, constants), + input::HINT_INPUT => self.hint_input(vm, exec_scope, hint_data, constants), + input::HINT_INPUT_PREV => self.hint_input_prev(vm, exec_scope, hint_data, constants), _ => Err(HintError::UnknownHint( hint_data.code.to_string().into_boxed_str(), )), @@ -72,6 +68,11 @@ impl HintProcessorLogic for CustomHintProcessor { return res; } + let res = hints::run_hint(vm, exec_scopes, hint_data, constants); + if !matches!(res, Err(HintError::UnknownHint(_))) { + return res; + } + self.run_hint(vm, exec_scopes, hint_data, constants) } } diff --git a/cairo_vm_hints/src/hint_processor/print.rs b/cairo_vm_hints/src/hint_processor/print.rs deleted file mode 100644 index 2a166da..0000000 --- a/cairo_vm_hints/src/hint_processor/print.rs +++ /dev/null @@ -1,118 +0,0 @@ -use super::CustomHintProcessor; -use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::{ - get_integer_from_var_name, get_relocatable_from_var_name, -}; -use cairo_vm::{ - hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData, - types::exec_scope::ExecutionScopes, - vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, - Felt252, -}; -use std::collections::HashMap; - -pub const HINT_PRINT_HASH: &str = "from tools.py.hints import print_u256\nprint(\"\\n\")\nprint_u256(ids.block_header_hash_little,f\"block_header_keccak_hash_{ids.index}\")\nprint_u256(ids.expected_block_hash,f\"expected_keccak_hash_{ids.index}\")"; -pub const HINT_PRINT_FINAL: &str = "print(\"new root poseidon\", ids.new_mmr_root_poseidon)\nprint(\"new root keccak\", ids.new_mmr_root_keccak.low, ids.new_mmr_root_keccak.high)\nprint(\"new size\", ids.mmr_array_len + ids.mmr_offset)"; - -impl CustomHintProcessor { - pub fn hint_print_hash( - &mut self, - vm: &mut VirtualMachine, - _exec_scope: &mut ExecutionScopes, - hint_data: &HintProcessorData, - _constants: &HashMap, - ) -> Result<(), HintError> { - let index = - get_integer_from_var_name("index", vm, &hint_data.ids_data, &hint_data.ap_tracking)?; - - let block_header_hash_little = get_relocatable_from_var_name( - "block_header_hash_little", - vm, - &hint_data.ids_data, - &hint_data.ap_tracking, - )?; - - let expected_block_hash = get_relocatable_from_var_name( - "expected_block_hash", - vm, - &hint_data.ids_data, - &hint_data.ap_tracking, - )?; - - let block_header_hash_little = vm - .get_continuous_range(block_header_hash_little, 2)? - .into_iter() - .map(|v| v.get_int()) - .collect::>>() - .unwrap(); - println!( - "block_header_hash_little_{}, {} {}", - index, block_header_hash_little[0], block_header_hash_little[1] - ); - - let expected_block_hash = vm - .get_continuous_range(expected_block_hash, 2)? - .into_iter() - .map(|v| v.get_int()) - .collect::>>() - .unwrap(); - println!( - "expected_block_hash_{}, {} {}", - index, expected_block_hash[0], expected_block_hash[1] - ); - - Ok(()) - } - - pub fn hint_print_final( - &mut self, - vm: &mut VirtualMachine, - _exec_scope: &mut ExecutionScopes, - hint_data: &HintProcessorData, - _constants: &HashMap, - ) -> Result<(), HintError> { - let new_mmr_root_poseidon = get_integer_from_var_name( - "new_mmr_root_poseidon", - vm, - &hint_data.ids_data, - &hint_data.ap_tracking, - )?; - - let new_mmr_root_keccak = get_relocatable_from_var_name( - "new_mmr_root_keccak", - vm, - &hint_data.ids_data, - &hint_data.ap_tracking, - )?; - - let mmr_array_len = get_integer_from_var_name( - "mmr_array_len", - vm, - &hint_data.ids_data, - &hint_data.ap_tracking, - )?; - - let mmr_offset = get_integer_from_var_name( - "mmr_offset", - vm, - &hint_data.ids_data, - &hint_data.ap_tracking, - )?; - - println!("new root poseidon: {}", new_mmr_root_poseidon); - - let new_mmr_root_keccak = vm - .get_continuous_range(new_mmr_root_keccak, 2)? - .into_iter() - .map(|v| v.get_int()) - .collect::>>() - .unwrap(); - println!( - "new root keccak: {} {}", - new_mmr_root_keccak[0], new_mmr_root_keccak[1] - ); - - println!("new size: {}", mmr_array_len + mmr_offset); - - Ok(()) - } -} diff --git a/cairo_vm_hints/src/hints/mod.rs b/cairo_vm_hints/src/hints/mod.rs new file mode 100644 index 0000000..01328c5 --- /dev/null +++ b/cairo_vm_hints/src/hints/mod.rs @@ -0,0 +1,28 @@ +use cairo_vm::{ + hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData, + types::exec_scope::ExecutionScopes, + vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, + Felt252, +}; +use std::collections::HashMap; + +pub mod print; + +pub fn run_hint( + vm: &mut VirtualMachine, + exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + constants: &HashMap, +) -> Result<(), HintError> { + let hints = [print::run_hint]; + + for hint in hints.iter() { + let res = hint(vm, exec_scope, hint_data, constants); + if !matches!(res, Err(HintError::UnknownHint(_))) { + return res; + } + } + Err(HintError::UnknownHint( + hint_data.code.to_string().into_boxed_str(), + )) +} diff --git a/cairo_vm_hints/src/hints/print.rs b/cairo_vm_hints/src/hints/print.rs new file mode 100644 index 0000000..c00d27e --- /dev/null +++ b/cairo_vm_hints/src/hints/print.rs @@ -0,0 +1,126 @@ +use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; +use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::{ + get_integer_from_var_name, get_relocatable_from_var_name, +}; +use cairo_vm::types::exec_scope::ExecutionScopes; +use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}; +use cairo_vm::Felt252; +use std::collections::HashMap; + +const HINT_PRINT_HASH: &str = "from tools.py.hints import print_u256\nprint(\"\\n\")\nprint_u256(ids.block_header_hash_little,f\"block_header_keccak_hash_{ids.index}\")\nprint_u256(ids.expected_block_hash,f\"expected_keccak_hash_{ids.index}\")"; +const HINT_PRINT_FINAL: &str = "print(\"new root poseidon\", ids.new_mmr_root_poseidon)\nprint(\"new root keccak\", ids.new_mmr_root_keccak.low, ids.new_mmr_root_keccak.high)\nprint(\"new size\", ids.mmr_array_len + ids.mmr_offset)"; + +fn hint_print_hash( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let index = + get_integer_from_var_name("index", vm, &hint_data.ids_data, &hint_data.ap_tracking)?; + + let block_header_hash_little = get_relocatable_from_var_name( + "block_header_hash_little", + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + let expected_block_hash = get_relocatable_from_var_name( + "expected_block_hash", + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + let block_header_hash_little = vm + .get_continuous_range(block_header_hash_little, 2)? + .into_iter() + .map(|v| v.get_int()) + .collect::>>() + .unwrap(); + println!( + "block_header_hash_little_{}, {} {}", + index, block_header_hash_little[0], block_header_hash_little[1] + ); + + let expected_block_hash = vm + .get_continuous_range(expected_block_hash, 2)? + .into_iter() + .map(|v| v.get_int()) + .collect::>>() + .unwrap(); + println!( + "expected_block_hash_{}, {} {}", + index, expected_block_hash[0], expected_block_hash[1] + ); + + Ok(()) +} + +fn hint_print_final( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let new_mmr_root_poseidon = get_integer_from_var_name( + "new_mmr_root_poseidon", + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + let new_mmr_root_keccak = get_relocatable_from_var_name( + "new_mmr_root_keccak", + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + let mmr_array_len = get_integer_from_var_name( + "mmr_array_len", + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + let mmr_offset = get_integer_from_var_name( + "mmr_offset", + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + println!("new root poseidon: {}", new_mmr_root_poseidon); + + let new_mmr_root_keccak = vm + .get_continuous_range(new_mmr_root_keccak, 2)? + .into_iter() + .map(|v| v.get_int()) + .collect::>>() + .unwrap(); + println!( + "new root keccak: {} {}", + new_mmr_root_keccak[0], new_mmr_root_keccak[1] + ); + + println!("new size: {}", mmr_array_len + mmr_offset); + + Ok(()) +} + +pub fn run_hint( + vm: &mut VirtualMachine, + exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + constants: &HashMap, +) -> Result<(), HintError> { + match hint_data.code.as_str() { + HINT_PRINT_HASH => hint_print_hash(vm, exec_scope, hint_data, constants), + HINT_PRINT_FINAL => hint_print_final(vm, exec_scope, hint_data, constants), + _ => Err(HintError::UnknownHint( + hint_data.code.to_string().into_boxed_str(), + )), + } +} diff --git a/cairo_vm_hints/src/lib.rs b/cairo_vm_hints/src/lib.rs index 4c0f40a..a80ed6a 100644 --- a/cairo_vm_hints/src/lib.rs +++ b/cairo_vm_hints/src/lib.rs @@ -1,2 +1,4 @@ pub mod hint_processor; +pub mod hints; + pub use hint_processor::{CustomHintProcessor, ExtendedHintProcessor}; diff --git a/cairo_vm_hints/src/main.rs b/cairo_vm_hints/src/main.rs index fef6502..4075378 100644 --- a/cairo_vm_hints/src/main.rs +++ b/cairo_vm_hints/src/main.rs @@ -1,12 +1,12 @@ #![deny(warnings)] #![forbid(unsafe_code)] pub mod hint_processor; +pub mod hints; use bincode::enc::write::Writer; use cairo_vm::air_public_input::PublicInputError; use cairo_vm::cairo_run::{self, EncodeTraceError}; use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::BuiltinHintProcessor; -// TODO // #[cfg(feature = "with_tracer")] // use cairo_vm::serde::deserialize_program::DebugInfo; use cairo_vm::types::layout::CairoLayoutParams; diff --git a/tools/make/prepare_inputs_api.py b/tools/make/prepare_inputs_api.py index 477fc6b..d5a8717 100755 --- a/tools/make/prepare_inputs_api.py +++ b/tools/make/prepare_inputs_api.py @@ -388,8 +388,8 @@ def prepare_full_chain_inputs( if __name__ == "__main__": output = prepare_full_chain_inputs( - from_block_number_high=19999, + from_block_number_high=99999, to_block_number_low=0, - batch_size=20000, + batch_size=100000, dynamic=False, )