diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d8744d0..4ea022b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,13 +28,6 @@ jobs: steps: - uses: actions/checkout@v4 - uses: asdf-vm/actions/install@v3 - - name: Prepare - shell: bash - run: | - sh scripts/0-venv.sh - sh scripts/1-compile.sh - sh scripts/2-merge.sh - ls -Rl examples/ - name: Build run: cargo build --verbose - name: Run tests diff --git a/Cargo.lock b/Cargo.lock index d1a27d1..23c70ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,29 +17,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "aes" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", -] - -[[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 = "aho-corasick" version = "1.1.3" @@ -49,27 +26,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "alloc-no-stdlib" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" - -[[package]] -name = "alloc-stdlib" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" -dependencies = [ - "alloc-no-stdlib", -] - -[[package]] -name = "allocator-api2" -version = "0.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" - [[package]] name = "android-tzdata" version = "0.1.1" @@ -87,9 +43,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.14" +version = "0.6.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" dependencies = [ "anstyle", "anstyle-parse", @@ -102,134 +58,58 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anstyle-parse" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.3" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" dependencies = [ "anstyle", "windows-sys 0.52.0", ] [[package]] -name = "anyhow" -version = "1.0.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" - -[[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 0.10.5", - "num-bigint", - "num-traits", - "paste", - "rustc_version", - "zeroize", -] - -[[package]] -name = "ark-ff-asm" -version = "0.4.2" +name = "async-stream" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" dependencies = [ - "quote", - "syn 1.0.109", + "async-stream-impl", + "futures-core", + "pin-project-lite", ] [[package]] -name = "ark-ff-macros" -version = "0.4.2" +name = "async-stream-impl" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" 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.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" - -[[package]] -name = "ascii-canvas" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8824ecca2e851cec16968d54a01dd372ef8f95b244fb84b84e70128be347c3c6" -dependencies = [ - "term", -] - -[[package]] -name = "async-compression" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd066d0b4ef8ecb03a55319dc13aa6910616d0f44008a045bb1835af830abff5" -dependencies = [ - "brotli", - "futures-core", - "memchr", - "pin-project-lite", - "tokio", + "syn", ] [[package]] @@ -240,7 +120,7 @@ checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn", ] [[package]] @@ -249,17 +129,6 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" -[[package]] -name = "auto_impl" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.71", -] - [[package]] name = "autocfg" version = "1.3.0" @@ -278,10 +147,10 @@ dependencies = [ "base64 0.21.7", "bytes", "futures-util", - "http 1.1.0", - "http-body 1.0.1", + "http", + "http-body", "http-body-util", - "hyper 1.4.1", + "hyper", "hyper-util", "itoa", "matchit", @@ -314,8 +183,8 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http 1.1.0", - "http-body 1.0.1", + "http", + "http-body", "http-body-util", "mime", "pin-project-lite", @@ -326,6 +195,29 @@ dependencies = [ "tracing", ] +[[package]] +name = "axum-extra" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0be6ea09c9b96cb5076af0de2e383bd2bc0c18f827cf1967bdd353e0b910d733" +dependencies = [ + "axum", + "axum-core", + "bytes", + "futures-util", + "headers", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "serde", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + [[package]] name = "axum-macros" version = "0.4.1" @@ -335,7 +227,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.71", + "syn", ] [[package]] @@ -353,12 +245,6 @@ dependencies = [ "rustc-demangle", ] -[[package]] -name = "base64" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" - [[package]] name = "base64" version = "0.21.7" @@ -377,57 +263,12 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" -[[package]] -name = "bigdecimal" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6773ddc0eafc0e509fb60e48dff7f450f8e674a0686ae8605e8d9901bd5eefa" -dependencies = [ - "num-bigint", - "num-integer", - "num-traits", - "serde", -] - -[[package]] -name = "bit-set" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" -dependencies = [ - "bit-vec", -] - -[[package]] -name = "bit-vec" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - [[package]] name = "bitflags" version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" -[[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" @@ -437,49 +278,12 @@ dependencies = [ "generic-array", ] -[[package]] -name = "brotli" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", - "brotli-decompressor", -] - -[[package]] -name = "brotli-decompressor" -version = "4.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", -] - -[[package]] -name = "bstr" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" -dependencies = [ - "memchr", - "serde", -] - [[package]] name = "bumpalo" version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" -[[package]] -name = "byte-slice-cast" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" - [[package]] name = "byteorder" version = "1.5.0" @@ -488,365 +292,37 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" - -[[package]] -name = "cairo-lang-compiler" -version = "2.7.0-rc.3" -source = "git+https://github.com/starkware-libs/cairo?tag=v2.7.0-rc.3#bd44f910883dc5149320eab9fa2f9ad35afa2b0e" -dependencies = [ - "anyhow", - "cairo-lang-defs", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-lowering", - "cairo-lang-parser", - "cairo-lang-project", - "cairo-lang-semantic", - "cairo-lang-sierra", - "cairo-lang-sierra-generator", - "cairo-lang-syntax", - "cairo-lang-utils", - "indoc", - "salsa", - "smol_str", - "thiserror", -] - -[[package]] -name = "cairo-lang-debug" -version = "2.7.0-rc.3" -source = "git+https://github.com/starkware-libs/cairo?tag=v2.7.0-rc.3#bd44f910883dc5149320eab9fa2f9ad35afa2b0e" -dependencies = [ - "cairo-lang-utils", -] - -[[package]] -name = "cairo-lang-defs" -version = "2.7.0-rc.3" -source = "git+https://github.com/starkware-libs/cairo?tag=v2.7.0-rc.3#bd44f910883dc5149320eab9fa2f9ad35afa2b0e" -dependencies = [ - "cairo-lang-debug", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-parser", - "cairo-lang-syntax", - "cairo-lang-utils", - "itertools 0.12.1", - "salsa", - "smol_str", -] - -[[package]] -name = "cairo-lang-diagnostics" -version = "2.7.0-rc.3" -source = "git+https://github.com/starkware-libs/cairo?tag=v2.7.0-rc.3#bd44f910883dc5149320eab9fa2f9ad35afa2b0e" -dependencies = [ - "cairo-lang-debug", - "cairo-lang-filesystem", - "cairo-lang-utils", - "itertools 0.12.1", -] - -[[package]] -name = "cairo-lang-filesystem" -version = "2.7.0-rc.3" -source = "git+https://github.com/starkware-libs/cairo?tag=v2.7.0-rc.3#bd44f910883dc5149320eab9fa2f9ad35afa2b0e" -dependencies = [ - "cairo-lang-debug", - "cairo-lang-utils", - "path-clean", - "salsa", - "serde", - "smol_str", -] - -[[package]] -name = "cairo-lang-formatter" -version = "2.7.0-rc.3" -source = "git+https://github.com/starkware-libs/cairo?tag=v2.7.0-rc.3#bd44f910883dc5149320eab9fa2f9ad35afa2b0e" -dependencies = [ - "anyhow", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-parser", - "cairo-lang-syntax", - "cairo-lang-utils", - "diffy", - "ignore", - "itertools 0.12.1", - "salsa", - "serde", - "smol_str", - "thiserror", -] - -[[package]] -name = "cairo-lang-lowering" -version = "2.7.0-rc.3" -source = "git+https://github.com/starkware-libs/cairo?tag=v2.7.0-rc.3#bd44f910883dc5149320eab9fa2f9ad35afa2b0e" -dependencies = [ - "cairo-lang-debug", - "cairo-lang-defs", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-parser", - "cairo-lang-proc-macros", - "cairo-lang-semantic", - "cairo-lang-syntax", - "cairo-lang-utils", - "id-arena", - "itertools 0.12.1", - "log", - "num-bigint", - "num-traits", - "once_cell", - "salsa", - "smol_str", -] - -[[package]] -name = "cairo-lang-parser" -version = "2.7.0-rc.3" -source = "git+https://github.com/starkware-libs/cairo?tag=v2.7.0-rc.3#bd44f910883dc5149320eab9fa2f9ad35afa2b0e" -dependencies = [ - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-syntax", - "cairo-lang-syntax-codegen", - "cairo-lang-utils", - "colored", - "itertools 0.12.1", - "num-bigint", - "num-traits", - "salsa", - "smol_str", - "unescaper", -] - -[[package]] -name = "cairo-lang-plugins" -version = "2.7.0-rc.3" -source = "git+https://github.com/starkware-libs/cairo?tag=v2.7.0-rc.3#bd44f910883dc5149320eab9fa2f9ad35afa2b0e" -dependencies = [ - "cairo-lang-defs", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-parser", - "cairo-lang-syntax", - "cairo-lang-utils", - "indent", - "indoc", - "itertools 0.12.1", - "salsa", - "smol_str", -] - -[[package]] -name = "cairo-lang-proc-macros" -version = "2.7.0-rc.3" -source = "git+https://github.com/starkware-libs/cairo?tag=v2.7.0-rc.3#bd44f910883dc5149320eab9fa2f9ad35afa2b0e" -dependencies = [ - "cairo-lang-debug", - "quote", - "syn 2.0.71", -] - -[[package]] -name = "cairo-lang-project" -version = "2.7.0-rc.3" -source = "git+https://github.com/starkware-libs/cairo?tag=v2.7.0-rc.3#bd44f910883dc5149320eab9fa2f9ad35afa2b0e" -dependencies = [ - "cairo-lang-filesystem", - "cairo-lang-utils", - "serde", - "smol_str", - "thiserror", - "toml", -] - -[[package]] -name = "cairo-lang-semantic" -version = "2.7.0-rc.3" -source = "git+https://github.com/starkware-libs/cairo?tag=v2.7.0-rc.3#bd44f910883dc5149320eab9fa2f9ad35afa2b0e" -dependencies = [ - "cairo-lang-debug", - "cairo-lang-defs", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-parser", - "cairo-lang-plugins", - "cairo-lang-proc-macros", - "cairo-lang-syntax", - "cairo-lang-test-utils", - "cairo-lang-utils", - "id-arena", - "indoc", - "itertools 0.12.1", - "num-bigint", - "num-traits", - "once_cell", - "salsa", - "smol_str", - "toml", -] - -[[package]] -name = "cairo-lang-sierra" -version = "2.7.0-rc.3" -source = "git+https://github.com/starkware-libs/cairo?tag=v2.7.0-rc.3#bd44f910883dc5149320eab9fa2f9ad35afa2b0e" -dependencies = [ - "anyhow", - "cairo-lang-utils", - "const-fnv1a-hash", - "convert_case", - "derivative", - "itertools 0.12.1", - "lalrpop", - "lalrpop-util", - "num-bigint", - "num-integer", - "num-traits", - "once_cell", - "regex", - "salsa", - "serde", - "serde_json", - "sha3", - "smol_str", - "starknet-types-core", - "thiserror", -] - -[[package]] -name = "cairo-lang-sierra-generator" -version = "2.7.0-rc.3" -source = "git+https://github.com/starkware-libs/cairo?tag=v2.7.0-rc.3#bd44f910883dc5149320eab9fa2f9ad35afa2b0e" -dependencies = [ - "cairo-lang-debug", - "cairo-lang-defs", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-lowering", - "cairo-lang-parser", - "cairo-lang-semantic", - "cairo-lang-sierra", - "cairo-lang-syntax", - "cairo-lang-utils", - "itertools 0.12.1", - "num-traits", - "once_cell", - "salsa", - "serde", - "serde_json", - "smol_str", -] - -[[package]] -name = "cairo-lang-syntax" -version = "2.7.0-rc.3" -source = "git+https://github.com/starkware-libs/cairo?tag=v2.7.0-rc.3#bd44f910883dc5149320eab9fa2f9ad35afa2b0e" -dependencies = [ - "cairo-lang-debug", - "cairo-lang-filesystem", - "cairo-lang-utils", - "num-bigint", - "num-traits", - "salsa", - "smol_str", - "unescaper", -] - -[[package]] -name = "cairo-lang-syntax-codegen" -version = "2.7.0-rc.3" -source = "git+https://github.com/starkware-libs/cairo?tag=v2.7.0-rc.3#bd44f910883dc5149320eab9fa2f9ad35afa2b0e" -dependencies = [ - "genco", - "xshell", -] - -[[package]] -name = "cairo-lang-test-utils" -version = "2.7.0-rc.3" -source = "git+https://github.com/starkware-libs/cairo?tag=v2.7.0-rc.3#bd44f910883dc5149320eab9fa2f9ad35afa2b0e" -dependencies = [ - "cairo-lang-formatter", - "cairo-lang-utils", - "colored", - "log", - "pretty_assertions", -] - -[[package]] -name = "cairo-lang-utils" -version = "2.7.0-rc.3" -source = "git+https://github.com/starkware-libs/cairo?tag=v2.7.0-rc.3#bd44f910883dc5149320eab9fa2f9ad35afa2b0e" -dependencies = [ - "hashbrown 0.14.5", - "indexmap 2.2.6", - "itertools 0.12.1", - "num-bigint", - "num-traits", - "schemars", - "serde", -] - -[[package]] -name = "cairo-proof-parser" -version = "0.1.0" -source = "git+https://github.com/cartridge-gg/cairo-proof-parser.git#8c5789d9afc7632e7747f48368c2f68dc273da2f" -dependencies = [ - "anyhow", - "clap", - "itertools 0.12.1", - "num-bigint", - "prefix-hex", - "regex", - "serde", - "serde-felt", - "serde_json", - "starknet", - "starknet-crypto", - "tokio", - "url", -] +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" [[package]] name = "cairo-prove" version = "0.1.0" dependencies = [ - "cairo-proof-parser", "clap", + "common", "ed25519-dalek", - "prefix-hex", - "prover", "prover-sdk", + "reqwest", "serde", "serde_json", + "starknet-types-core", "thiserror", "tokio", + "tracing", + "tracing-subscriber", "url", ] -[[package]] -name = "cairo1-compile" -version = "0.1.0" -dependencies = [ - "cairo-lang-compiler", - "cairo-lang-sierra", - "clap", - "serde", - "serde_json", -] - [[package]] name = "cc" -version = "1.1.5" +version = "1.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "324c74f2155653c90b04f25b2a47a8a631360cb908f92a772695f430c7e31052" +checksum = "50d2eb3cd3d1bf4529e31c215ee6f93ec5a3d536d9f578f93d9d33ee19562932" +dependencies = [ + "shlex", +] [[package]] name = "cfg-if" @@ -866,24 +342,14 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.52.6", -] - -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common", - "inout", + "windows-targets", ] [[package]] name = "clap" -version = "4.5.9" +version = "4.5.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64acc1846d54c1fe936a78dc189c34e28d3f5afc348403f28ecf53660b9b8462" +checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019" dependencies = [ "clap_builder", "clap_derive", @@ -891,9 +357,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.9" +version = "4.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8393d67ba2e7bfaf28a23458e4e2b543cc73a99595511eb207fdb8aede942" +checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" dependencies = [ "anstream", "anstyle", @@ -903,79 +369,45 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.8" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085" +checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.71", + "syn", ] [[package]] name = "clap_lex" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "colorchoice" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" - -[[package]] -name = "colored" -version = "2.1.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" -dependencies = [ - "lazy_static", - "windows-sys 0.48.0", -] +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" [[package]] name = "common" version = "0.1.0" dependencies = [ "ed25519-dalek", - "prefix-hex", - "serde", - "serde_json", - "serde_with 3.9.0", -] - -[[package]] -name = "config-generator" -version = "0.1.0" -source = "git+https://github.com/piotr-stec/genereate-config.git#bdbaf09990f7b8fd7c836d666cfdb120753e3ec7" -dependencies = [ "serde", "serde_json", + "serde_with", + "starknet-types-core", ] -[[package]] -name = "const-fnv1a-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b13ea120a812beba79e34316b3942a857c86ec1593cb34f27bb28272ce2cca" - [[package]] name = "const-oid" version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" -[[package]] -name = "convert_case" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "cookie" version = "0.17.0" @@ -1032,71 +464,21 @@ dependencies = [ "url", ] -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" 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-deque" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - -[[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" @@ -1118,15 +500,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "ctr" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" -dependencies = [ - "cipher", -] - [[package]] name = "curve25519-dalek" version = "4.1.3" @@ -1151,7 +524,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn", ] [[package]] @@ -1175,7 +548,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.71", + "syn", ] [[package]] @@ -1186,7 +559,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.71", + "syn", ] [[package]] @@ -1215,32 +588,6 @@ dependencies = [ "serde", ] -[[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 = "diff" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" - -[[package]] -name = "diffy" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e616e59155c92257e84970156f506287853355f58cd4a6eb167385722c32b790" -dependencies = [ - "nu-ansi-term", -] - [[package]] name = "digest" version = "0.10.7" @@ -1252,33 +599,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "dirs-next" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" -dependencies = [ - "cfg-if", - "dirs-sys-next", -] - -[[package]] -name = "dirs-sys-next" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - -[[package]] -name = "dyn-clone" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" - [[package]] name = "ed25519" version = "2.2.3" @@ -1305,21 +625,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "either" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" - -[[package]] -name = "ena" -version = "0.14.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5" -dependencies = [ - "log", -] - [[package]] name = "encoding_rs" version = "0.8.34" @@ -1336,53 +641,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] -name = "eth-keystore" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fda3bf123be441da5260717e0661c25a2fd9cb2b2c1d20bf2e05580047158ab" -dependencies = [ - "aes", - "ctr", - "digest", - "hex", - "hmac", - "pbkdf2", - "rand", - "scrypt", - "serde", - "serde_json", - "sha2", - "sha3", - "thiserror", - "uuid", -] - -[[package]] -name = "ethbloom" -version = "0.13.0" +name = "errno" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ - "crunchy", - "fixed-hash", - "impl-rlp", - "impl-serde", - "tiny-keccak", + "libc", + "windows-sys 0.52.0", ] [[package]] -name = "ethereum-types" -version = "0.14.1" +name = "fastrand" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" -dependencies = [ - "ethbloom", - "fixed-hash", - "impl-rlp", - "impl-serde", - "primitive-types", - "uint", -] +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "fiat-crypto" @@ -1390,34 +662,6 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" -[[package]] -name = "fixed-hash" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" -dependencies = [ - "byteorder", - "rand", - "rustc-hex", - "static_assertions", -] - -[[package]] -name = "fixedbitset" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" - -[[package]] -name = "flate2" -version = "1.0.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - [[package]] name = "fnv" version = "1.0.7" @@ -1434,10 +678,19 @@ dependencies = [ ] [[package]] -name = "funty" -version = "2.0.0" +name = "futures" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] [[package]] name = "futures-channel" @@ -1455,12 +708,34 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + [[package]] name = "futures-io" version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "futures-sink" version = "0.3.30" @@ -1479,8 +754,10 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ + "futures-channel", "futures-core", "futures-io", + "futures-macro", "futures-sink", "futures-task", "memchr", @@ -1489,28 +766,6 @@ dependencies = [ "slab", ] -[[package]] -name = "genco" -version = "0.17.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afac3cbb14db69ac9fef9cdb60d8a87e39a7a527f85a81a923436efa40ad42c6" -dependencies = [ - "genco-macros", - "relative-path", - "smallvec", -] - -[[package]] -name = "genco-macros" -version = "0.17.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "553630feadf7b76442b0849fd25fdf89b860d933623aec9693fed19af0400c78" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.71", -] - [[package]] name = "generic-array" version = "0.14.7" @@ -1540,51 +795,19 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" -[[package]] -name = "globset" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" -dependencies = [ - "aho-corasick", - "bstr", - "log", - "regex-automata 0.4.7", - "regex-syntax 0.8.4", -] - -[[package]] -name = "h2" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http 0.2.12", - "indexmap 2.2.6", - "slab", - "tokio", - "tokio-util", - "tracing", -] - [[package]] name = "h2" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" +checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" dependencies = [ "atomic-waker", "bytes", "fnv", "futures-core", "futures-sink", - "http 1.1.0", - "indexmap 2.2.6", + "http", + "indexmap 2.4.0", "slab", "tokio", "tokio-util", @@ -1602,19 +825,29 @@ name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "headers" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "322106e6bd0cba2d5ead589ddb8150a13d7c4217cf80d7c4f682ca994ccc6aa9" dependencies = [ - "ahash", - "allocator-api2", - "serde", + "base64 0.21.7", + "bytes", + "headers-core", + "http", + "httpdate", + "mime", + "sha1", ] [[package]] -name = "heck" -version = "0.3.3" +name = "headers-core" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4" dependencies = [ - "unicode-segmentation", + "http", ] [[package]] @@ -1650,17 +883,6 @@ dependencies = [ "digest", ] -[[package]] -name = "http" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - [[package]] name = "http" version = "1.1.0" @@ -1672,17 +894,6 @@ dependencies = [ "itoa", ] -[[package]] -name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes", - "http 0.2.12", - "pin-project-lite", -] - [[package]] name = "http-body" version = "1.0.1" @@ -1690,7 +901,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.1.0", + "http", ] [[package]] @@ -1701,8 +912,8 @@ checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", "futures-util", - "http 1.1.0", - "http-body 1.0.1", + "http", + "http-body", "pin-project-lite", ] @@ -1718,30 +929,6 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" -[[package]] -name = "hyper" -version = "0.14.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2 0.3.26", - "http 0.2.12", - "http-body 0.4.6", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "want", -] - [[package]] name = "hyper" version = "1.4.1" @@ -1751,9 +938,9 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2 0.4.5", - "http 1.1.0", - "http-body 1.0.1", + "h2", + "http", + "http-body", "httparse", "httpdate", "itoa", @@ -1763,20 +950,6 @@ dependencies = [ "want", ] -[[package]] -name = "hyper-rustls" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" -dependencies = [ - "futures-util", - "http 0.2.12", - "hyper 0.14.30", - "rustls 0.21.12", - "tokio", - "tokio-rustls 0.24.1", -] - [[package]] name = "hyper-rustls" version = "0.27.2" @@ -1784,29 +957,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155" dependencies = [ "futures-util", - "http 1.1.0", - "hyper 1.4.1", + "http", + "hyper", "hyper-util", - "rustls 0.23.11", + "rustls", "rustls-pki-types", "tokio", - "tokio-rustls 0.26.0", + "tokio-rustls", "tower-service", - "webpki-roots 0.26.3", + "webpki-roots", ] [[package]] name = "hyper-util" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ab92f4f49ee4fb4f997c784b7a2e0fa70050211e0b6a287f898c3c9785ca956" +checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9" dependencies = [ "bytes", "futures-channel", "futures-util", - "http 1.1.0", - "http-body 1.0.1", - "hyper 1.4.1", + "http", + "http-body", + "hyper", "pin-project-lite", "socket2", "tokio", @@ -1838,12 +1011,6 @@ dependencies = [ "cc", ] -[[package]] -name = "id-arena" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" - [[package]] name = "ident_case" version = "1.0.1" @@ -1870,66 +1037,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "ignore" -version = "0.4.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1" -dependencies = [ - "crossbeam-deque", - "globset", - "log", - "memchr", - "regex-automata 0.4.7", - "same-file", - "walkdir", - "winapi-util", -] - -[[package]] -name = "impl-codec" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" -dependencies = [ - "parity-scale-codec", -] - -[[package]] -name = "impl-rlp" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" -dependencies = [ - "rlp", -] - -[[package]] -name = "impl-serde" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" -dependencies = [ - "serde", -] - -[[package]] -name = "impl-trait-for-tuples" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "indent" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9f1a0777d972970f204fdf8ef319f1f4f8459131636d7e3c96c5d59570d0fa6" - [[package]] name = "indexmap" version = "1.9.3" @@ -1943,39 +1050,15 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.6" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" dependencies = [ "equivalent", "hashbrown 0.14.5", "serde", ] -[[package]] -name = "indoc" -version = "2.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" - -[[package]] -name = "inout" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" -dependencies = [ - "generic-array", -] - -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if", -] - [[package]] name = "ipnet" version = "2.9.0" @@ -1984,36 +1067,9 @@ checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] name = "is_terminal_polyfill" -version = "1.70.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.12.1" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itoa" @@ -2023,9 +1079,9 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "js-sys" -version = "0.3.69" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" dependencies = [ "wasm-bindgen", ] @@ -2061,37 +1117,6 @@ dependencies = [ "prover-sdk", ] -[[package]] -name = "lalrpop" -version = "0.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cb077ad656299f160924eb2912aa147d7339ea7d69e1b5517326fdcec3c1ca" -dependencies = [ - "ascii-canvas", - "bit-set", - "ena", - "itertools 0.11.0", - "lalrpop-util", - "petgraph", - "pico-args", - "regex", - "regex-syntax 0.8.4", - "string_cache", - "term", - "tiny-keccak", - "unicode-xid", - "walkdir", -] - -[[package]] -name = "lalrpop-util" -version = "0.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "507460a910eb7b32ee961886ff48539633b788a36b65692b95f225b844c82553" -dependencies = [ - "regex-automata 0.4.7", -] - [[package]] name = "lambdaworks-crypto" version = "0.7.0" @@ -2122,19 +1147,15 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.155" +version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" [[package]] -name = "libredox" -version = "0.1.3" +name = "linux-raw-sys" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" -dependencies = [ - "bitflags 2.6.0", - "libc", -] +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "lock_api" @@ -2190,13 +1211,14 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.11" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ + "hermit-abi", "libc", "wasi", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2208,7 +1230,7 @@ dependencies = [ "bytes", "encoding_rs", "futures-util", - "http 1.1.0", + "http", "httparse", "memchr", "mime", @@ -2216,12 +1238,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "new_debug_unreachable" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" - [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -2240,7 +1256,6 @@ checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits", - "serde", ] [[package]] @@ -2267,21 +1282,11 @@ dependencies = [ "autocfg", ] -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi", - "libc", -] - [[package]] name = "object" -version = "0.36.1" +version = "0.36.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce" +checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" dependencies = [ "memchr", ] @@ -2292,55 +1297,12 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" -[[package]] -name = "oorandom" -version = "11.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" - [[package]] name = "overload" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" -[[package]] -name = "parity-scale-codec" -version = "3.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" -dependencies = [ - "arrayvec", - "bitvec", - "byte-slice-cast", - "impl-trait-for-tuples", - "parity-scale-codec-derive", - "serde", -] - -[[package]] -name = "parity-scale-codec-derive" -version = "3.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.6", -] - [[package]] name = "parking_lot" version = "0.12.3" @@ -2348,21 +1310,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", - "parking_lot_core 0.9.10", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall 0.2.16", - "smallvec", - "winapi", + "parking_lot_core", ] [[package]] @@ -2373,30 +1321,9 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.2", + "redox_syscall", "smallvec", - "windows-targets 0.52.6", -] - -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "path-clean" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17359afc20d7ab31fdb42bb844c8b3bb1dabd7dcf7e68428492da7f16966fcef" - -[[package]] -name = "pbkdf2" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" -dependencies = [ - "digest", + "windows-targets", ] [[package]] @@ -2415,31 +1342,6 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" -[[package]] -name = "petgraph" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" -dependencies = [ - "fixedbitset", - "indexmap 2.2.6", -] - -[[package]] -name = "phf_shared" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" -dependencies = [ - "siphasher", -] - -[[package]] -name = "pico-args" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" - [[package]] name = "pin-project" version = "1.1.5" @@ -2457,7 +1359,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn", ] [[package]] @@ -2490,15 +1392,12 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - -[[package]] -name = "precomputed-hash" -version = "0.1.1" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] [[package]] name = "prefix-hex" @@ -2509,38 +1408,6 @@ dependencies = [ "hex", ] -[[package]] -name = "pretty_assertions" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" -dependencies = [ - "diff", - "yansi", -] - -[[package]] -name = "primitive-types" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" -dependencies = [ - "fixed-hash", - "impl-codec", - "impl-rlp", - "impl-serde", - "uint", -] - -[[package]] -name = "proc-macro-crate" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" -dependencies = [ - "toml_edit 0.21.1", -] - [[package]] name = "proc-macro2" version = "1.0.86" @@ -2554,46 +1421,46 @@ dependencies = [ name = "prover" version = "0.1.0" dependencies = [ + "async-stream", "axum", + "axum-extra", + "base64 0.22.1", "bytes", "chrono", "clap", "common", - "config-generator", - "curve25519-dalek", "ed25519-dalek", + "futures", "jsonwebtoken", - "lazy_static", + "once_cell", "prefix-hex", "rand", "serde", "serde_json", - "serde_with 3.9.0", + "serde_with", + "starknet-types-core", + "tempfile", "thiserror", "tokio", - "tower-http", "tracing", "tracing-subscriber", - "utils", ] [[package]] name = "prover-sdk" version = "0.1.0" dependencies = [ - "bytes", + "base64 0.22.1", "common", "ed25519-dalek", - "http 1.1.0", - "hyper-util", + "futures", "prefix-hex", - "prover", "rand", - "reqwest 0.12.5", + "reqwest", "reqwest_cookie_store", "serde", "serde_json", - "serde_with 3.9.0", + "starknet-types-core", "thiserror", "tokio", "tracing", @@ -2618,16 +1485,17 @@ dependencies = [ [[package]] name = "quinn" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4ceeeeabace7857413798eb1ffa1e9c905a9946a57d81fb69b4b71c4d8eb3ad" +checksum = "b22d8e7369034b9a7132bc2008cac12f2013c8132b45e0554e6e20e2617f2156" dependencies = [ "bytes", "pin-project-lite", "quinn-proto", "quinn-udp", "rustc-hash", - "rustls 0.23.11", + "rustls", + "socket2", "thiserror", "tokio", "tracing", @@ -2635,15 +1503,15 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.3" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddf517c03a109db8100448a4be38d498df8a210a99fe0e1b9eaf39e78c640efe" +checksum = "ba92fb39ec7ad06ca2582c0ca834dfeadcaf06ddfc8e635c80aa7e1c05315fdd" dependencies = [ "bytes", "rand", "ring", "rustc-hash", - "rustls 0.23.11", + "rustls", "slab", "thiserror", "tinyvec", @@ -2652,31 +1520,26 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25a78e6f726d84fcf960409f509ae354a32648f090c8d32a2ea8b1a1bc3bab14" +checksum = "8bffec3605b73c6f1754535084a85229fa8a30f86014e6c81aeec4abb68b0285" dependencies = [ "libc", "once_cell", "socket2", + "tracing", "windows-sys 0.52.0", ] [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +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" @@ -2709,38 +1572,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_syscall" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" -dependencies = [ - "bitflags 2.6.0", -] - -[[package]] -name = "redox_users" -version = "0.4.6" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" dependencies = [ - "getrandom", - "libredox", - "thiserror", + "bitflags", ] [[package]] name = "regex" -version = "1.10.5" +version = "1.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" dependencies = [ "aho-corasick", "memchr", @@ -2788,62 +1631,15 @@ dependencies = [ "ed25519-dalek", "prefix-hex", "prover-sdk", - "tokio", - "url", -] - -[[package]] -name = "relative-path" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" - -[[package]] -name = "reqwest" -version = "0.11.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" -dependencies = [ - "base64 0.21.7", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2 0.3.26", - "http 0.2.12", - "http-body 0.4.6", - "hyper 0.14.30", - "hyper-rustls 0.24.2", - "ipnet", - "js-sys", - "log", - "mime", - "once_cell", - "percent-encoding", - "pin-project-lite", - "rustls 0.21.12", - "rustls-pemfile 1.0.4", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper 0.1.2", - "system-configuration", - "tokio", - "tokio-rustls 0.24.1", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "webpki-roots 0.25.4", - "winreg 0.50.0", + "tokio", + "url", ] [[package]] name = "reqwest" -version = "0.12.5" +version = "0.12.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37" +checksum = "f8f4955649ef5c38cc7f9e8aa41761d48fb9677197daea9984dc54f56aad5e63" dependencies = [ "base64 0.22.1", "bytes", @@ -2852,11 +1648,11 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "http 1.1.0", - "http-body 1.0.1", + "http", + "http-body", "http-body-util", - "hyper 1.4.1", - "hyper-rustls 0.27.2", + "hyper", + "hyper-rustls", "hyper-util", "ipnet", "js-sys", @@ -2866,22 +1662,24 @@ dependencies = [ "percent-encoding", "pin-project-lite", "quinn", - "rustls 0.23.11", - "rustls-pemfile 2.1.2", + "rustls", + "rustls-pemfile", "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", "sync_wrapper 1.0.1", "tokio", - "tokio-rustls 0.26.0", + "tokio-rustls", + "tokio-util", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", + "wasm-streams", "web-sys", - "webpki-roots 0.26.3", - "winreg 0.52.0", + "webpki-roots", + "windows-registry", ] [[package]] @@ -2892,7 +1690,7 @@ checksum = "93ea5c6f30c19d766efe8d823c88f9abd1c56516648a0d4264ab2dc04cc19472" dependencies = [ "bytes", "cookie_store 0.20.0", - "reqwest 0.12.5", + "reqwest", "url", ] @@ -2921,16 +1719,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "rlp" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" -dependencies = [ - "bytes", - "rustc-hex", -] - [[package]] name = "rustc-demangle" version = "0.1.24" @@ -2939,65 +1727,51 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustc-hex" -version = "2.1.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" +checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] [[package]] -name = "rustls" -version = "0.21.12" +name = "rustix" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "log", - "ring", - "rustls-webpki 0.101.7", - "sct", + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", ] [[package]] name = "rustls" -version = "0.23.11" +version = "0.23.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4828ea528154ae444e5a642dbb7d5623354030dc9822b83fd9bb79683c7399d0" +checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044" dependencies = [ "once_cell", "ring", "rustls-pki-types", - "rustls-webpki 0.102.5", + "rustls-webpki", "subtle", "zeroize", ] [[package]] name = "rustls-pemfile" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" -dependencies = [ - "base64 0.21.7", -] - -[[package]] -name = "rustls-pemfile" -version = "2.1.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" +checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425" dependencies = [ "base64 0.22.1", "rustls-pki-types", @@ -3005,25 +1779,15 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" - -[[package]] -name = "rustls-webpki" -version = "0.101.7" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" -dependencies = [ - "ring", - "untrusted", -] +checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" [[package]] name = "rustls-webpki" -version = "0.102.5" +version = "0.102.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a6fccd794a42c2c105b513a2f62bc3fd8f3ba57a4593677ceb0bd035164d78" +checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e" dependencies = [ "ring", "rustls-pki-types", @@ -3042,106 +1806,12 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" -[[package]] -name = "salsa" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b84d9f96071f3f3be0dc818eae3327625d8ebc95b58da37d6850724f31d3403" -dependencies = [ - "crossbeam-utils", - "indexmap 1.9.3", - "lock_api", - "log", - "oorandom", - "parking_lot 0.11.2", - "rustc-hash", - "salsa-macros", - "smallvec", -] - -[[package]] -name = "salsa-macros" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd3904a4ba0a9d0211816177fd34b04c7095443f8cdacd11175064fe541c8fe2" -dependencies = [ - "heck 0.3.3", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "salsa20" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" -dependencies = [ - "cipher", -] - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "schemars" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92" -dependencies = [ - "dyn-clone", - "indexmap 1.9.3", - "schemars_derive", - "serde", - "serde_json", -] - -[[package]] -name = "schemars_derive" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1eee588578aff73f856ab961cd2f79e36bc45d7ded33a7562adba4667aecc0e" -dependencies = [ - "proc-macro2", - "quote", - "serde_derive_internals", - "syn 2.0.71", -] - [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "scrypt" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f9e24d2b632954ded8ab2ef9fea0a0c769ea56ea98bddbafbad22caeeadf45d" -dependencies = [ - "hmac", - "pbkdf2", - "salsa20", - "sha2", -] - -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "semver" version = "1.0.23" @@ -3150,63 +1820,32 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.204" +version = "1.0.209" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" +checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" dependencies = [ "serde_derive", ] -[[package]] -name = "serde-felt" -version = "0.1.0" -source = "git+https://github.com/cartridge-gg/cairo-proof-parser.git#8c5789d9afc7632e7747f48368c2f68dc273da2f" -dependencies = [ - "serde", - "starknet-crypto", - "starknet-ff", -] - [[package]] name = "serde_derive" -version = "1.0.204" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.71", -] - -[[package]] -name = "serde_derive_internals" -version = "0.29.1" +version = "1.0.209" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" +checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn", ] [[package]] name = "serde_json" -version = "1.0.120" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_json_pythonic" -version = "0.1.2" +version = "1.0.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62212da9872ca2a0cad0093191ee33753eddff9266cbbc1b4a602d13a3a768db" +checksum = "8043c06d9f82bd7271361ed64f415fe5e12a77fdb52e573e7f06a516dea329ad" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] @@ -3221,15 +1860,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_spanned" -version = "0.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" -dependencies = [ - "serde", -] - [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -3242,22 +1872,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_with" -version = "2.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07ff71d2c147a7b57362cead5e22f772cd52f6ab31cfcd9edcd7f6aeb2a0afbe" -dependencies = [ - "base64 0.13.1", - "chrono", - "hex", - "indexmap 1.9.3", - "serde", - "serde_json", - "serde_with_macros 2.3.3", - "time", -] - [[package]] name = "serde_with" version = "3.9.0" @@ -3268,26 +1882,14 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.2.6", + "indexmap 2.4.0", "serde", "serde_derive", "serde_json", - "serde_with_macros 3.9.0", + "serde_with_macros", "time", ] -[[package]] -name = "serde_with_macros" -version = "2.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn 2.0.71", -] - [[package]] name = "serde_with_macros" version = "3.9.0" @@ -3297,7 +1899,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.71", + "syn", ] [[package]] @@ -3341,6 +1943,12 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signal-hook-registry" version = "1.4.2" @@ -3371,12 +1979,6 @@ dependencies = [ "time", ] -[[package]] -name = "siphasher" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" - [[package]] name = "slab" version = "0.4.9" @@ -3392,15 +1994,6 @@ version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" -[[package]] -name = "smol_str" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" -dependencies = [ - "serde", -] - [[package]] name = "socket2" version = "0.5.7" @@ -3424,205 +2017,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", - "der", -] - -[[package]] -name = "starknet" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20b9a7b7bfd87287af85854f7458b8170ba6aa59c39113436532b7ff3d2fcbd8" -dependencies = [ - "starknet-accounts", - "starknet-contract", - "starknet-core", - "starknet-crypto", - "starknet-ff", - "starknet-macros", - "starknet-providers", - "starknet-signers", -] - -[[package]] -name = "starknet-accounts" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2095d7584608ae1707bd1cf2889368ab3734d9f54e4fcef4765cba1f3b3f7618" -dependencies = [ - "async-trait", - "auto_impl", - "starknet-core", - "starknet-providers", - "starknet-signers", - "thiserror", -] - -[[package]] -name = "starknet-contract" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb3b73d437b4d62241612d13fce612602de6684c149cccf696e76a20757e2156" -dependencies = [ - "serde", - "serde_json", - "serde_with 2.3.3", - "starknet-accounts", - "starknet-core", - "starknet-providers", - "thiserror", -] - -[[package]] -name = "starknet-core" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ed286d637e34fb8ae1cd2f9615120ec8ff38d1cffd311ed7fdd497cdd2bd01f" -dependencies = [ - "base64 0.21.7", - "flate2", - "hex", - "serde", - "serde_json", - "serde_json_pythonic", - "serde_with 2.3.3", - "sha3", - "starknet-crypto", - "starknet-ff", -] - -[[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", - "starknet-ff", - "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", - "starknet-ff", - "syn 2.0.71", -] - -[[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-ff" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7abf1b44ec5b18d87c1ae5f54590ca9d0699ef4dd5b2ffa66fc97f24613ec585" -dependencies = [ - "ark-ff", - "bigdecimal", - "crypto-bigint", - "getrandom", - "hex", - "num-bigint", - "serde", -] - -[[package]] -name = "starknet-macros" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95d549d3078bdbe775d0deaa8ddb57a19942989ce7c1f2dfd60beeb322bb4945" -dependencies = [ - "starknet-core", - "syn 2.0.71", -] - -[[package]] -name = "starknet-providers" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6abf40ffcbe3b887b4d5cfc8ab73170c816b4aa78d1d4ad59abd3fb3b0f53cd" -dependencies = [ - "async-trait", - "auto_impl", - "ethereum-types", - "flate2", - "log", - "reqwest 0.11.27", - "serde", - "serde_json", - "serde_with 2.3.3", - "starknet-core", - "thiserror", - "url", -] - -[[package]] -name = "starknet-signers" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e9a2bd4fd66090003c3b7f0d76476e5b63cd44f6a49ede2442673f4427d5a40" -dependencies = [ - "async-trait", - "auto_impl", - "crypto-bigint", - "eth-keystore", - "rand", - "starknet-core", - "starknet-crypto", - "thiserror", + "der", ] [[package]] name = "starknet-types-core" version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6bacf0ba19bc721e518bc4bf389ff13daa8a7c5db5fd320600473b8aa9fcbd" +source = "git+https://github.com/neotheprogramist/types-rs.git?branch=fix/2-types#ad226a91c21b74c63c920216caa8df0a7bff64cb" dependencies = [ + "crypto-bigint", + "hmac", "lambdaworks-crypto", "lambdaworks-math", - "lazy_static", "num-bigint", "num-integer", "num-traits", + "rfc6979", "serde", -] - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "string_cache" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" -dependencies = [ - "new_debug_unreachable", - "once_cell", - "parking_lot 0.12.3", - "phf_shared", - "precomputed-hash", + "sha2", + "zeroize", ] [[package]] @@ -3639,20 +2052,9 @@ 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.71" +version = "2.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462" +checksum = "f6af063034fc1935ede7be0122941bafa9bacb949334d090b77ca98b5817c7d9" dependencies = [ "proc-macro2", "quote", @@ -3670,63 +2072,41 @@ name = "sync_wrapper" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" - -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" dependencies = [ - "core-foundation-sys", - "libc", + "futures-core", ] [[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - -[[package]] -name = "term" -version = "0.7.0" +name = "tempfile" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" +checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" dependencies = [ - "dirs-next", - "rustversion", - "winapi", + "cfg-if", + "fastrand", + "once_cell", + "rustix", + "windows-sys 0.59.0", ] [[package]] name = "thiserror" -version = "1.0.62" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2675633b1499176c2dff06b0856a27976a8f9d436737b4cf4f312d4d91d8bbb" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.62" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d20468752b09f49e909e55a5d338caa8bedf615594e9d80bc4c565d30faf798c" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn", ] [[package]] @@ -3770,15 +2150,6 @@ dependencies = [ "time-core", ] -[[package]] -name = "tiny-keccak" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" -dependencies = [ - "crunchy", -] - [[package]] name = "tinyvec" version = "1.8.0" @@ -3796,42 +2167,31 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.38.0" +version = "1.39.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" +checksum = "9babc99b9923bfa4804bd74722ff02c0381021eafa4db9949217e3be8e84fff5" dependencies = [ "backtrace", "bytes", "libc", "mio", - "num_cpus", - "parking_lot 0.12.3", + "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", -] - -[[package]] -name = "tokio-rustls" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" -dependencies = [ - "rustls 0.21.12", - "tokio", + "syn", ] [[package]] @@ -3840,7 +2200,7 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "rustls 0.23.11", + "rustls", "rustls-pki-types", "tokio", ] @@ -3870,51 +2230,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "toml" -version = "0.8.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac2caab0bf757388c6c0ae23b3293fdb463fee59434529014f85e3263b995c28" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit 0.22.16", -] - -[[package]] -name = "toml_datetime" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" -dependencies = [ - "indexmap 2.2.6", - "toml_datetime", - "winnow 0.5.40", -] - -[[package]] -name = "toml_edit" -version = "0.22.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "278f3d518e152219c994ce877758516bca5e118eaed6996192a774fb9fbf0788" -dependencies = [ - "indexmap 2.2.6", - "serde", - "serde_spanned", - "toml_datetime", - "winnow 0.6.18", -] - [[package]] name = "tower" version = "0.4.13" @@ -3931,38 +2246,17 @@ dependencies = [ "tracing", ] -[[package]] -name = "tower-http" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" -dependencies = [ - "async-compression", - "bitflags 2.6.0", - "bytes", - "futures-core", - "http 1.1.0", - "http-body 1.0.1", - "http-body-util", - "pin-project-lite", - "tokio", - "tokio-util", - "tower-layer", - "tower-service", - "tracing", -] - [[package]] name = "tower-layer" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" [[package]] name = "tower-service" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" @@ -3984,7 +2278,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn", ] [[package]] @@ -4041,7 +2335,7 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http 1.1.0", + "http", "httparse", "log", "rand", @@ -4057,27 +2351,6 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" -[[package]] -name = "uint" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] - -[[package]] -name = "unescaper" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c878a167baa8afd137494101a688ef8c67125089ff2249284bd2b5f9bfedb815" -dependencies = [ - "thiserror", -] - [[package]] name = "unicode-bidi" version = "0.3.15" @@ -4099,18 +2372,6 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "unicode-segmentation" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" - -[[package]] -name = "unicode-xid" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a" - [[package]] name = "untrusted" version = "0.9.0" @@ -4126,7 +2387,6 @@ dependencies = [ "form_urlencoded", "idna 0.5.0", "percent-encoding", - "serde", ] [[package]] @@ -4141,23 +2401,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" -[[package]] -name = "utils" -version = "0.1.0" -dependencies = [ - "tokio", -] - -[[package]] -name = "uuid" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" -dependencies = [ - "getrandom", - "serde", -] - [[package]] name = "valuable" version = "0.1.0" @@ -4166,19 +2409,9 @@ checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" [[package]] name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "walkdir" -version = "2.5.0" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "want" @@ -4197,34 +2430,35 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" dependencies = [ "cfg-if", + "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.71", + "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.42" +version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" dependencies = [ "cfg-if", "js-sys", @@ -4234,9 +2468,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4244,38 +2478,45 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" [[package]] -name = "web-sys" -version = "0.3.69" +name = "wasm-streams" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129" dependencies = [ + "futures-util", "js-sys", "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", ] [[package]] -name = "webpki-roots" -version = "0.25.4" +name = "web-sys" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" +checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" +dependencies = [ + "js-sys", + "wasm-bindgen", +] [[package]] name = "webpki-roots" @@ -4302,15 +2543,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -[[package]] -name = "winapi-util" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" -dependencies = [ - "windows-sys 0.48.0", -] - [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -4323,16 +2555,37 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.6", + "windows-targets", ] [[package]] -name = "windows-sys" -version = "0.48.0" +name = "windows-registry" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +dependencies = [ + "windows-result", + "windows-strings", + "windows-targets", +] + +[[package]] +name = "windows-result" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" dependencies = [ - "windows-targets 0.48.5", + "windows-targets", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets", ] [[package]] @@ -4341,22 +2594,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.6", + "windows-targets", ] [[package]] -name = "windows-targets" -version = "0.48.5" +name = "windows-sys" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", + "windows-targets", ] [[package]] @@ -4365,46 +2612,28 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - [[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.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[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.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -4417,128 +2646,37 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[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.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - [[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.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[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.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - -[[package]] -name = "winnow" -version = "0.6.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" -dependencies = [ - "memchr", -] - -[[package]] -name = "winreg" -version = "0.50.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - -[[package]] -name = "winreg" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - -[[package]] -name = "xshell" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db0ab86eae739efd1b054a8d3d16041914030ac4e01cd1dca0cf252fd8b6437" -dependencies = [ - "xshell-macros", -] - -[[package]] -name = "xshell-macros" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d422e8e38ec76e2f06ee439ccc765e9c6a9638b9e7c9f2e8255e4d41e8bd852" - -[[package]] -name = "yansi" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" - [[package]] name = "zerocopy" version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ + "byteorder", "zerocopy-derive", ] @@ -4550,7 +2688,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn", ] [[package]] @@ -4558,17 +2696,3 @@ 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.71", -] diff --git a/Cargo.toml b/Cargo.toml index f690378..5a3935a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,58 +1,46 @@ [workspace] resolver = "2" members = [ + "prover", + "common", + "prover-sdk", "bin/cairo-prove", "bin/keygen", "bin/register", - "crates/common", - "crates/utils", - "prover", - "prover-sdk", - "cairo1-compile", ] - [workspace.package] version = "0.1.0" edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [workspace.dependencies] axum = { version = "0.7.5", features = ["http2", "macros", "multipart", "ws"] } -bytes = "1.4.0" -cairo-proof-parser = { git = "https://github.com/cartridge-gg/cairo-proof-parser.git" } -chrono = "0.4.38" -clap = { version = "4.5.4", features = ["derive", "env"] } -common = { path = "crates/common" } -curve25519-dalek = "4.1.2" -ed25519-dalek = { version = "2.1.1", features = ["rand_core", "serde"] } -http = "1.1.0" -hyper-util = "0.1.3" +clap = { version = "4.5.16", features = ["derive", "env"] } +tracing = "0.1.40" +tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } +tokio = { version = "1.39.3", features = ["full"] } +thiserror = "1.0.63" +serde_json = "1.0.127" +tempfile = "3.12.0" +serde = { version = "1.0.209", features = ["derive"] } +common = { path = "common" } +prover-sdk = { path = "prover-sdk" } +reqwest = { version = "0.12.7", features = [ + "blocking", + "json", + "rustls-tls", + "stream", +], default-features = false } +reqwest_cookie_store = "0.7.0" +url = "2.5.2" jsonwebtoken = "9.3.0" -lazy_static = "1.4.0" +axum-extra = { version = "0.9.3", features = ["typed-header"] } +once_cell = "1.19.0" +serde_with = "3.9.0" +bytes = "1.7.1" prefix-hex = "0.7.1" -prover = { path = "prover" } -prover-sdk = { path = "prover-sdk" } rand = "0.8.5" -reqwest = { version = "0.12.4", features = ["blocking", "json", "rustls-tls"], default-features = false } -reqwest_cookie_store = "0.7.0" -serde = { version = "1.0.197", features = ["derive"] } -serde_json = "1.0.116" -serde_with = "3.8.1" -thiserror = "1.0.57" -tokio = { version = "1.37.0", features = ["full"] } -tower-http = { version = "0.5.2", features = [ - "limit", - "timeout", - "trace", - "decompression-br", - "set-header", - "cors", -] } -tracing = "0.1.40" -tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } -url = { version = "2.5.0", features = ["serde"] } -utils = { path = "crates/utils" } -config-generator = { git = "https://github.com/piotr-stec/genereate-config.git" } -cairo-lang-compiler = { git = "https://github.com/starkware-libs/cairo", tag = "v2.7.0-rc.3", default-features = false } -cairo-lang-sierra = { git = "https://github.com/starkware-libs/cairo", tag = "v2.7.0-rc.3", default-features = false } \ No newline at end of file +ed25519-dalek = { version = "2.1.1", features = ["rand_core", "serde"] } +chrono = "0.4.38" +base64 = "0.22.1" +starknet-types-core = { git = "https://github.com/neotheprogramist/types-rs.git", branch = "fix/2-types" } +futures = "0.3.30" +async-stream = "0.3.5" \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 97348a2..9fe8e90 100644 --- a/Dockerfile +++ b/Dockerfile @@ -40,10 +40,6 @@ RUN rm -rf cairo RUN pip install cairo-lang==0.13.1 RUN pip install sympy==1.12.1 -RUN mkdir resources/ -RUN mkdir resources/cairo/ -RUN mkdir resources/cairoZero/ - EXPOSE 3000 ENTRYPOINT [ "prover" ] diff --git a/README.md b/README.md index c67ad74..28b6a82 100644 --- a/README.md +++ b/README.md @@ -1,131 +1,87 @@ -# Prover SDK +# Cairo Proving System -The Prover SDK is a Rust library for interacting with the Prover service. It provides functionality for authentication, proving, and error handling. +This repository contains a comprehensive toolset for proving computations using the Cairo language. The repository includes a server, an SDK for interacting with the server, a binary `cairo-prove` for executing proofs, and helper binaries such as `keygen` and `register`. -## Generating access keys +## Table of Contents -Before using the prover key has to be authorized by the prover operator. To generate the key use: +- [Overview](#overview) +- [Components](#components) + - [Server](#server) + - [SDK](#sdk) + - [Cairo-Prove Binary](#cairo-prove-binary) + - [Keygen Binary](#keygen-binary) + - [Register Binary](#register-binary) + - [Common Library](#common-library) +- [Examples](#examples) +- [Scripts](#scripts) -```bash -cargo run --bin keygen -``` +## Overview -It will output 2 keys. +The Cairo Proving System provides tools to prove and verify computations written in the Cairo language. This repository includes: -- send the public key to the prover operator -- pass the private key to the sdk to use it. +1. A **server** that manages and verifies proofs. +2. An **SDK** to interact with the server programmatically. +3. A **cairo-prove binary** that implements the SDK and allows users to perform proofs from the command line. +4. Helper binaries like **keygen** and **register** to manage keys and registration. -## Using in code +## Components -First parse a private key corresponding to an authorized public key. +### Server -```rust -ProverAccessKey::from_hex_string( - "0xf91350db1ca372b54376b519be8bf73a7bbbbefc4ffe169797bc3f5ea2dec740", -) -.unwrap() -``` +The server is the core of the proving system. It handles proof requests, manages authorization, and verifies proofs. -Then construct an instance with +- **Directory:** `prover` +- **Description:** The server is built using a modular design, with components handling authentication, proof generation, verification, and a thread pool to manage concurrent tasks. +- **Inner README:** [Server README](prover/README.md) -```rust -let prover_url = Url::parse("http://localhost:3000").unwrap(); -let sdk = ProverSDK::new(key, prover_url).await?; -``` +### SDK -Then you can use below to prove an execution +The SDK provides a Rust-based interface for interacting with the server. It abstracts the underlying API calls and simplifies the development of client applications. -```rust -let data = load_cairo1(PathBuf::from("../prover/resources/input_cairo1.json")).await?; -let proof = sdk.prove_cairo1(data).await; -``` +- **Directory:** `prover-sdk` +- **Description:** The SDK includes modules for handling access keys, managing errors, and building client requests. +- **Inner README:** [SDK README](prover-sdk/README.md) -# Operating a prover +### Cairo-Prove Binary -To run the sdk first make sure prover/authorized_keys.json contains your public_key. +The `cairo-prove` binary is a command-line tool that leverages the SDK to perform proofs. It’s intended for users who want to interact with the proving system without writing custom code. -Run the following command in your terminal: +- **Inner README:** [Cairo-Prove README](bin/cairo-prove/README.md) -```bash -cargo run -p prover -- --jwt-secret-key --message-expiration-time --session-expiration-time --authorized-keys , -``` +### Keygen Binary -Alternatively use the flag `--authorized-keys-path authorized_keys.json` instead of `--authorized-keys` to load keys from a json file. It needs to have the format below +The `keygen` binary is a helper tool for generating cryptographic keys required by the server and SDK. -```json -["", ""] -``` +- **Inner README:** [Keygen README](bin/keygen/README.md) -Note: -Tests from the sdk lib.rs file should be run separately. +### Register Binary -## Using sdk +The `register` binary is used to register new keys with the server. +- **Inner README:** [Register README](bin/register/README.md) -Run command below to generate keys. Pass the public key to operator, after he includes it to the prover you will be able to use sdk. +### Common Library -```bash -cargo run --bin keygen -``` +The common library provides shared utilities and data structures used across the various components. -## Usage +- **Directory:** `common` +- **Description:** Includes modules for handling prover inputs, requests, and shared models. -To use the SDK, follow these steps: +## Examples -Authenticate with the Prover service using your private key and the authentication URL: +Examples demonstrating how to use the tools are provided in the `examples` directory. These include: -```rust -#[tokio::main] -async fn main() -> Result<(), ProverSdkErrors> { - let private_key_hex : String= env::var("PRIVATE_KEY")?; - let url_auth = "http://localhost:3000/auth"; - let url_prover = "http://localhost:3000/prove/cairo1"; +- **Cairo Examples:** `examples/cairo` +- **Cairo 0 Examples:** `examples/cairo0` - let result = ProverSDK::new(url_auth, url_prover) - .auth(&private_key_hex) - .await?; +Each example contains necessary inputs and compiled programs to run with the `cairo-prove` binary. - // Handle authentication result - Ok(()) -} -``` +## Scripts -Use the SDK to prove data: +Helper scripts are included in the `scripts` directory for tasks like running end-to-end tests. -```rust -#[tokio::main] -async fn main() -> Result<(), ProverSdkErrors> { - // Authentication code goes here... +- **End-to-End Testing Script:** `scripts/e2e_test.sh` - let sdk = result.build()?; - let data = read_json_file("resources/input.json").await?; - let proof = sdk.prove(data).await?; +## Getting Started - // Handle proof result - Ok(()) -} -``` +To get started with the Cairo Proving System, please refer to the individual READMEs linked above for detailed instructions on building, configuring, and running each component. -Handle errors using the provided error types: - -```rust -#[tokio::main] -async fn main() -> Result<(), ProverSdkErrors> { - // Authentication code goes here... - - let result = ProverSDK::new(url_auth, url_prover) - .auth(&private_key_hex) - .await; - - match result { - Ok(sdk) => { - // Continue with SDK usage... - } - Err(err) => { - // Handle authentication error - println!("Authentication failed: {}", err); - } - } - - Ok(()) -} -``` diff --git a/bin/cairo-prove/Cargo.toml b/bin/cairo-prove/Cargo.toml index 3014eab..983ddc5 100644 --- a/bin/cairo-prove/Cargo.toml +++ b/bin/cairo-prove/Cargo.toml @@ -4,16 +4,16 @@ version.workspace = true edition.workspace = true [dependencies] -clap.workspace = true -ed25519-dalek.workspace = true -prefix-hex.workspace = true prover-sdk.workspace = true -tokio.workspace = true +clap.workspace = true url.workspace = true serde.workspace = true -serde_json.workspace = true thiserror.workspace = true - -[dev-dependencies] -prover.workspace = true -cairo-proof-parser.workspace = true +common.workspace = true +serde_json.workspace = true +tokio.workspace = true +tracing.workspace = true +tracing-subscriber.workspace = true +reqwest.workspace = true +ed25519-dalek.workspace = true +starknet-types-core.workspace = true \ No newline at end of file diff --git a/bin/cairo-prove/README.md b/bin/cairo-prove/README.md index ad1accf..116fe6b 100644 --- a/bin/cairo-prove/README.md +++ b/bin/cairo-prove/README.md @@ -1,53 +1,81 @@ -# `prove` +# Cairo Prove +## Overview -```sh -cargo run --bin cairo-prove -- --key --cairo-version <1/0> --url your_input.json > output.json -``` +This application is a command-line tool designed to run the SDK for http-prover. The tool processes input files, validates the data, and generates the corresponding proofs. -By default cairo version is set to cairo 1 -test workflow +## Table of Contents -## Input format +- [Installation](#installation) +- [Cli Arguments](#command-line-arguments) + - [Input for cairo](#input-for-cairo) + - [Input for cairo0](#input-for-cairo0) + - [Output](#output) + - [Parameters](#parameters) +- [Examples](#examples) -```json -{ - "program":{program}, - "program_input":{program input}, - "layout":{program input} // `recursive` is good option -} +## Installation + +To install the application, clone this repository and build the binary: + +```bash +cargo install --git https://github.com/cartridge-gg/http-prover.git cairo-prove ``` +## Command-Line Arguments +### The following command-line arguments and environment variables are available to configure the behavior of the application: -# Output +`--prover-url` (PROVER_URL): Specifies the URL of the prover service. This is a required argument that the application uses to connect to the prover service. -scheduler outputs file with proof in result.json file +`--cairo-version` (CAIRO_VERSION, `default: v1`): Defines the version of Cairo to be used. This can be set to v1 or v0 for Cairo0. -```json -{ - proof -} -``` +`--layout` (LAYOUT): Specifies the layout used for the execution of the Cairo program. This argument determines the memory layout and other execution parameters. For example: `recursive` -# Testing prover with fibonacci +`--program-path `(PROGRAM_PATH): Indicates the path to the Cairo program that will run and executed. This argument is mandatory and must point to the valid, compiled to `.sierra.json` program file. -To test prover we have to have compiled cairo program, and merged with input. -We can do it for Cairo Zero with: +`--program-input-path` (PROGRAM_INPUT_PATH): Provides the path to the input file for the program, which is required if the cairo_version is set to v0. *This flag cannot be used together with the `program_input` flag.* -```rust -cargo make --makefile Makefile.toml prepareCairoZero -``` +`--program-input` (PROGRAM_INPUT): Specifies the input data for the program as a comma-separated list of strings. This input is used directly by the program. This flag is not compatible with program_input_path and is *used only when cairo_version is v1*. -For Cairo: +`--program-output`(PROGRAM_OUTPUT): Specifies the path where the program's output will be saved. The output of the execution will be written to this file. -```rust -cargo make --makefile Makefile.toml prepareCairo -``` +`--prover-access-key` (PROVER_ACCESS_KEY): Provides the access key required to authenticate with the prover service. This argument must be private key in hex format -# Run tests +`--wait` (WAIT, default: false): A flag that determines whether the application should wait for the prover's response synchronously. If set to true, the application will block until the prover completes its task, if set to false it ends and returns job, which can be retrived with `get-job` endpoint +Each of these arguments can be set via command-line flags or environment variables, allowing for flexible configuration depending on your deployment environment and needs. + +## Input for Cairo + +The application expects input in the form of a file that contains data formatted as an array of strings or integers. The format should adhere to the following guidelines: + +- The input file should contain a single array of values +- Values should be separated by commas `,` without spaces. +- Each value should be either a hex or a numeric type that can be parsed into a `Felt`. + +**Example Input:** + +```plaintext +1,2,3,4,5 ``` -cargo test --package prove --test prove -- test_cairo0_fibonacci -``` +## Input for Cairo0 +The application expects input in the form of a json file that contains valid json object. +**Example Input:** +``` +{ + "fibonacci_claim_index": 10 +} ``` -cargo test --package prove --test prove -- test_cairo1_fibonacci +### Output + +The output of the application depends on --wait flag,it can be job id or the generated cryptographic proof, which will be saved to a specified output file + + +### Examples + +**Basic Example:** + +To generate a proof from an input file and print the result to the console: + +```bash +cairo-prove --prover-url http://localhost:3000 --layout recursive --program-path examples/cairo/fibonacci_compiled.json --program-input-path examples/cairo/input.json --wait --program-output proof.json --prover-access-key 0xf5061793648ab019cc27d6c9a2bd8a2b651f9224ae9ae2c0990fd32ed2172f48 ``` diff --git a/bin/cairo-prove/src/errors.rs b/bin/cairo-prove/src/errors.rs new file mode 100644 index 0000000..8b91716 --- /dev/null +++ b/bin/cairo-prove/src/errors.rs @@ -0,0 +1,22 @@ +use reqwest::Error as ReqwestError; +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum ProveErrors { + #[error(transparent)] + SdkErrors(#[from] prover_sdk::errors::SdkErrors), + #[error(transparent)] + UrlParseError(#[from] url::ParseError), + #[error(transparent)] + IoError(#[from] std::io::Error), + #[error("Prover response error: {0}")] + ProveResponseError(String), + #[error("Missing program input")] + MissingProgramInput, + #[error(transparent)] + Parse(#[from] serde_json::Error), + #[error(transparent)] + RequestFailed(#[from] ReqwestError), + #[error("{0}")] + Custom(String), +} diff --git a/bin/cairo-prove/src/fetch.rs b/bin/cairo-prove/src/fetch.rs new file mode 100644 index 0000000..9879f13 --- /dev/null +++ b/bin/cairo-prove/src/fetch.rs @@ -0,0 +1,32 @@ +use prover_sdk::sdk::ProverSDK; +use serde::Deserialize; +use serde_json::Value; + +use crate::errors::ProveErrors; + +#[derive(Deserialize)] +pub struct JobId { + pub job_id: u64, +} + +pub async fn fetch_job(sdk: ProverSDK, job: String) -> Result { + let job: JobId = serde_json::from_str(&job)?; + println!("Job ID: {}", job.job_id); + sdk.sse(job.job_id).await?; + let response = sdk.get_job(job.job_id).await?; + let response = response.text().await?; + let json_response: Value = serde_json::from_str(&response)?; + if let Some(status) = json_response.get("status").and_then(Value::as_str) { + if status == "Completed" { + return Ok(json_response + .get("result") + .and_then(Value::as_str) + .unwrap_or("No result found") + .to_string()); + } else { + Err(ProveErrors::Custom(json_response.to_string())) + } + } else { + Err(ProveErrors::Custom(json_response.to_string())) + } +} diff --git a/bin/cairo-prove/src/lib.rs b/bin/cairo-prove/src/lib.rs index df67ebc..d706e39 100644 --- a/bin/cairo-prove/src/lib.rs +++ b/bin/cairo-prove/src/lib.rs @@ -1,62 +1,118 @@ -use clap::Parser; -use prover_sdk::{Cairo0ProverInput, Cairo1ProverInput, ProverAccessKey, ProverSDK}; +use clap::{Parser, ValueEnum}; +use errors::ProveErrors; use serde::{Deserialize, Serialize}; -use thiserror::Error; +use starknet_types_core::felt::Felt; +use std::{path::PathBuf, str::FromStr}; use url::Url; -#[derive(Error, Debug)] -pub enum ProveError { - #[error("Failed to read: {0}")] - Read(#[from] tokio::io::Error), +pub mod errors; +pub mod fetch; +pub mod prove; - #[error("Failed to parse prover key")] - DecodeKey(prefix_hex::Error), - - #[error("Failed to initialize or authenticate prover SDK")] - Initialize(prover_sdk::ProverSdkErrors), +#[derive(Debug, Serialize, Deserialize, ValueEnum, Clone)] +pub enum CairoVersion { + V0, + V1, +} - #[error("Failed to parse input: {0}")] - ParseInput(#[from] serde_json::Error), +impl FromStr for CairoVersion { + type Err = String; - #[error("Failed to prove: {0}")] - Prove(prover_sdk::ProverSdkErrors), + fn from_str(input: &str) -> Result { + match input { + "v0" => Ok(CairoVersion::V0), + "v1" => Ok(CairoVersion::V1), + _ => Err(format!("Invalid Cairo version: {}", input)), + } + } } -#[derive(Parser, Debug, Serialize, Deserialize)] +#[derive(Parser, Debug, Clone)] #[clap(author, version, about, long_about = None)] -pub struct CliInput { - #[arg(short = 'k', long)] - pub key: String, - - #[arg(short, long, default_value_t = 1)] - pub cairo_version: usize, // 0 or 1, - - #[arg(short, long)] - pub url: Url, +pub struct Args { + #[arg(long, env)] + pub prover_url: Url, + #[arg(long, short, env, default_value = "v1")] + pub cairo_version: CairoVersion, + #[arg(long, short, env)] + pub layout: String, + #[arg(long, env)] + pub program_path: PathBuf, + #[arg( + long, + env, + conflicts_with("program_input"), + required_if_eq("cairo_version", "v0") + )] + pub program_input_path: Option, + #[arg(long, env, value_delimiter = ',')] + pub program_input: Vec, + #[arg(long, env)] + pub program_output: PathBuf, + #[arg(long, env)] + pub prover_access_key: String, + #[arg(long, env, default_value = "false")] + pub wait: bool, } -pub async fn prove(args: CliInput, input: String) -> Result { - let secret_key = ProverAccessKey::from_hex_string(&args.key).map_err(ProveError::DecodeKey)?; - let sdk = ProverSDK::new(secret_key, args.url) - .await - .map_err(ProveError::Initialize)?; +fn validate_input(input: &str) -> Result, ProveErrors> { + let parts: Vec<&str> = input.split(',').collect(); - let proof = match args.cairo_version { - 0 => { - let input: Cairo0ProverInput = - serde_json::from_str(&input).map_err(ProveError::ParseInput)?; - sdk.prove_cairo0(input).await.map_err(ProveError::Prove)? + let mut felts = Vec::new(); + for part in parts { + let part = part.replace(['[', '\n', ']'], ""); + match part.trim().parse::() { + Ok(num) => felts.push(num), + Err(_) => { + return Err(ProveErrors::Custom( + "Input contains non-numeric characters or spaces".to_string(), + )) + } } - 1 => { - let input: Cairo1ProverInput = - serde_json::from_str(&input).map_err(ProveError::ParseInput)?; - sdk.prove_cairo1(input).await.map_err(ProveError::Prove)? - } - _ => panic!("Invalid cairo version"), - }; - - let proof_json: serde_json::Value = - serde_json::from_str(&proof).expect("Failed to parse result"); - - Ok(serde_json::to_string_pretty(&proof_json).expect("Failed to serialize result")) + } + Ok(felts) +} +#[cfg(test)] +mod test { + use super::*; + #[test] + fn test_validate_input() -> Result<(), ProveErrors> { + let input = "1,2,3,4,5"; + let result = validate_input(input)?; + assert_eq!( + result, + vec![ + Felt::from(1), + Felt::from(2), + Felt::from(3), + Felt::from(4), + Felt::from(5) + ] + ); + Ok(()) + } + #[test] + fn test_validate_input_with_hex() -> Result<(), ProveErrors> { + let input = "[0x1,0x2,0x3,0x4,0x5]"; + let result = validate_input(input)?; + assert_eq!( + result, + vec![ + Felt::from(1), + Felt::from(2), + Felt::from(3), + Felt::from(4), + Felt::from(5) + ] + ); + Ok(()) + } + #[test] + fn test_validate_input_non_numeric() -> Result<(), ProveErrors> { + let input = "[1,2,a,4,5]"; + let result = validate_input(input); + println!("{:?}", result); + assert!(result.is_err()); + Ok(()) + } } diff --git a/bin/cairo-prove/src/main.rs b/bin/cairo-prove/src/main.rs index 4440bb2..f99c626 100644 --- a/bin/cairo-prove/src/main.rs +++ b/bin/cairo-prove/src/main.rs @@ -1,15 +1,20 @@ -use cairo_prove::{prove, CliInput, ProveError}; +use cairo_prove::errors::ProveErrors; +use cairo_prove::prove::prove; +use cairo_prove::{fetch::fetch_job, Args}; use clap::Parser; -use tokio::io::{self, AsyncReadExt}; - +use prover_sdk::access_key::ProverAccessKey; +use prover_sdk::sdk::ProverSDK; #[tokio::main] -pub async fn main() -> Result<(), ProveError> { - let args = CliInput::parse(); - - // Assume the input data is in JSON format as required by the SDK - let mut input = String::new(); - io::stdin().read_to_string(&mut input).await?; - - println!("{}", prove(args, input).await?); +pub async fn main() -> Result<(), ProveErrors> { + tracing_subscriber::fmt().init(); + let args = Args::parse(); + let access_key = ProverAccessKey::from_hex_string(&args.prover_access_key.clone())?; + let sdk = ProverSDK::new(args.prover_url.clone(), access_key).await?; + let job = prove(args.clone(), sdk.clone()).await?; + if args.wait { + let job = fetch_job(sdk, job).await?; + let path: std::path::PathBuf = args.program_output; + std::fs::write(path, job)?; + } Ok(()) } diff --git a/bin/cairo-prove/src/prove.rs b/bin/cairo-prove/src/prove.rs new file mode 100644 index 0000000..98ae7a0 --- /dev/null +++ b/bin/cairo-prove/src/prove.rs @@ -0,0 +1,47 @@ +use crate::errors::ProveErrors; +use crate::validate_input; +use crate::Args; +use crate::CairoVersion; +use common::{ + cairo0_prover_input::{Cairo0CompiledProgram, Cairo0ProverInput}, + cairo_prover_input::{CairoCompiledProgram, CairoProverInput}, +}; +use prover_sdk::sdk::ProverSDK; +use serde_json::Value; + +pub async fn prove(args: Args, sdk: ProverSDK) -> Result { + let program = std::fs::read_to_string(&args.program_path)?; + let proof = match args.cairo_version { + CairoVersion::V0 => { + let input_path = args + .program_input_path + .ok_or(ProveErrors::MissingProgramInput)?; + let input = std::fs::read_to_string(&input_path)?; + let program_serialized: Cairo0CompiledProgram = serde_json::from_str(&program)?; + let program_input: Value = serde_json::from_str(&input)?; + let data = Cairo0ProverInput { + program: program_serialized, + layout: args.layout, + program_input, + }; + sdk.prove_cairo0(data).await? + } + CairoVersion::V1 => { + let input = match args.clone().program_input_path { + Some(input_path) => { + let input = std::fs::read_to_string(input_path)?; + validate_input(&input)? + } + None => args.program_input, + }; + let program_serialized: CairoCompiledProgram = serde_json::from_str(&program)?; + let data = CairoProverInput { + program: program_serialized, + layout: args.layout, + program_input: input, + }; + sdk.prove_cairo(data).await? + } + }; + Ok(proof) +} diff --git a/bin/cairo-prove/tests/common.rs b/bin/cairo-prove/tests/common.rs deleted file mode 100644 index bd08669..0000000 --- a/bin/cairo-prove/tests/common.rs +++ /dev/null @@ -1,14 +0,0 @@ -use std::path::PathBuf; -use tokio::fs::File; -use tokio::io::AsyncReadExt; - -pub async fn read_file(path: PathBuf) -> Result { - let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - let file_path = manifest_dir.join("../../").join(path); - println!("Reading file: {:?}", file_path); - - let mut file = File::open(file_path).await?; - let mut contents = String::new(); - file.read_to_string(&mut contents).await?; - Ok(contents) -} diff --git a/bin/cairo-prove/tests/prove.rs b/bin/cairo-prove/tests/prove.rs deleted file mode 100644 index c857f3f..0000000 --- a/bin/cairo-prove/tests/prove.rs +++ /dev/null @@ -1,51 +0,0 @@ -use crate::common::read_file; -use cairo_proof_parser::output::{extract_output, ExtractOutputResult}; -use cairo_prove::{prove, CliInput}; -use serde_json::Value; -use std::path::PathBuf; -use url::Url; -mod common; - -#[tokio::test] -async fn test_cairo1_fibonacci() -> Result<(), cairo_prove::ProveError> { - let key = "0x5883b0e30b008e48af3d0bf5cfc138fb6093496da6f87d24b65def88470356d3"; - let args = CliInput { - key: key.to_string(), - cairo_version: 1, - url: Url::parse("http://localhost:3040").unwrap(), - }; - - let prover_input = - read_file(PathBuf::from("examples/Cairo/fibonacci_prover_input.json")).await?; - let proof = prove(args, prover_input).await?; - assert!(extract_output(&proof).is_ok()); - Ok(()) -} -#[tokio::test] -async fn test_cairo0_fibonacci() -> Result<(), cairo_prove::ProveError> { - let key = "0x5883b0e30b008e48af3d0bf5cfc138fb6093496da6f87d24b65def88470356d3"; - let args = CliInput { - key: key.to_string(), - cairo_version: 0, - url: Url::parse("http://localhost:3040").unwrap(), - }; - let prover_input = read_file(PathBuf::from("examples/CairoZero/prover_input.json")).await?; - let program_input: Value = serde_json::from_str(&prover_input)?; - - let fibonacci_claim_index = program_input - .get("program_input") - .and_then(|v| v.get("fibonacci_claim_index")) - .and_then(|v| v.as_u64()) - .unwrap(); - - let proof = prove(args, prover_input).await?; - - let ExtractOutputResult { program_output, .. } = extract_output(&proof).unwrap(); - let expected_input: u64 = program_output[0].try_into().unwrap(); - - assert_eq!( - expected_input, fibonacci_claim_index, - "Fibonacci index mismatch." - ); - Ok(()) -} diff --git a/bin/keygen/README.md b/bin/keygen/README.md new file mode 100644 index 0000000..ff5acbc --- /dev/null +++ b/bin/keygen/README.md @@ -0,0 +1,22 @@ + +# Prover Key Generation + +This is a simple command-line tool for generating new keys using the Prover SDK. + +## Installation +1. Clone the repository: + +```bash +git clone https://github.com/cartridge-gg/http-prover.git +``` + +## Usage +```bash +cargo run -p keygen +``` +## Output + +```bash +Public key: 0x88e496a53918755f93aae20f8fdfff01f710633825239c264bc4395e3346f3f3, provide it to the server operator. +Private key: 0x400532c40c61ad35c04a1f5b3a10394abb2442209dc4047aeb6a8f76ce47473d, pass this to the sdk to gain access, keep it secret. +``` diff --git a/bin/keygen/src/main.rs b/bin/keygen/src/main.rs index cf40ac7..7bf06f2 100644 --- a/bin/keygen/src/main.rs +++ b/bin/keygen/src/main.rs @@ -1,5 +1,7 @@ +use prover_sdk::access_key::ProverAccessKey; + fn main() { - let key = prover_sdk::ProverAccessKey::generate(); + let key = ProverAccessKey::generate(); println!( "Public key: {}, provide it to the server operator.", key.verifying_key_as_hex_string() diff --git a/bin/register/README.md b/bin/register/README.md new file mode 100644 index 0000000..9bd91e1 --- /dev/null +++ b/bin/register/README.md @@ -0,0 +1,57 @@ +# Prover Key Registration +This project provides a command-line tool for registering new keys with the Prover SDK. +## **To register a new key in Prover, ensure that your signing key is configured as the admin key in Prover.** + +## Table of Contents +- [Installation](#installation) +- [Arguments](#arguments) +- [Usage](#usage) + + + +## Installation + +```bash +cargo install --git https://github.com/chudkowsky/http_prover_refactored.git register +``` +or alternatively +```bash +git clone https://github.com/chudkowsky/http_prover_refactored.git +cargo build +cargo run -p register +``` + +## Arguments + +- `--private-key` (`-p`): The private key used to authenticate with the Prover SDK. This should be provided as a hex string. +- `--added-key` (`-k`): The public key you wish to register, also provided as a hex string. +- `--url` (`-u`): The URL of the Prover SDK server. + +## Usage + +To run the program, you need to provide three arguments: `--private-key`, `--added-key`, and `--url`. These can be provided either via command-line arguments or environment variables. + +### Command-Line Arguments +```bash +register --private-key --added-key --url +``` +or +```bash +cargo run -p register -- --private-key --added-key --url +``` +### Environment Variables + +You can also set the arguments via environment variables: + +```bash +export PRIVATE_KEY= +export ADDED_KEY= +export URL= +``` +```bash +register +``` +or +```bash +cargo run -p register +``` diff --git a/bin/register/src/main.rs b/bin/register/src/main.rs index 1209d2e..c43d402 100644 --- a/bin/register/src/main.rs +++ b/bin/register/src/main.rs @@ -1,6 +1,6 @@ use clap::{arg, Parser}; use ed25519_dalek::VerifyingKey; -use prover_sdk::{ProverAccessKey, ProverSDK}; +use prover_sdk::{access_key::ProverAccessKey, sdk::ProverSDK}; use url::Url; /// Command line arguments for the server @@ -23,7 +23,7 @@ async fn main() { let key = ProverAccessKey::from_hex_string(&args.private_key).unwrap(); - let mut sdk = ProverSDK::new(key, args.url) + let mut sdk = ProverSDK::new(args.url, key) .await .expect("Failed to create SDK instance"); diff --git a/cairo1-compile/Cargo.toml b/cairo1-compile/Cargo.toml deleted file mode 100644 index a47b908..0000000 --- a/cairo1-compile/Cargo.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -name = "cairo1-compile" -version.workspace = true -edition.workspace = true - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -cairo-lang-compiler.workspace = true -cairo-lang-sierra.workspace = true -clap.workspace = true -serde.workspace = true -serde_json.workspace = true diff --git a/cairo1-compile/README.md b/cairo1-compile/README.md deleted file mode 100644 index 842fdb0..0000000 --- a/cairo1-compile/README.md +++ /dev/null @@ -1,26 +0,0 @@ - -# Installation Guide - -Follow the steps below to install `cairo1-compile` and `cairo1-run`. - -## Install `cairo1-compile` - -To install `cairo1-compile`, run the following command: - -```sh -cargo install --path cairo1-compile -``` - -## Install `cairo1-run` - -To install `cairo1-run` from the repository, run the following command: - -```sh -cargo install --git https://github.com/lambdaclass/cairo-vm cairo1-run -``` - - -`cairo1-compile compile --output resources/fibonacci_compiled.sierra.json e2e_test/Cairo/fibonacci.cairo` -`cairo1-compile merge -o resources/fibonacci_prover_input.json resources/fibonacci_compiled.sierra.json e2e_test/Cairo/input.json` -`podman build -t stone5-cairo1:recursive -f Dockerfile .` -`podman run -i --rm stone5-cairo1:recursive < resources/fibonacci_prover_input.json > resources/proof.json` diff --git a/cairo1-compile/src/main.rs b/cairo1-compile/src/main.rs deleted file mode 100644 index 83999de..0000000 --- a/cairo1-compile/src/main.rs +++ /dev/null @@ -1,122 +0,0 @@ -use std::{ - fmt, - fs::File, - io::{BufReader, Write}, - path::{Path, PathBuf}, -}; - -use cairo_lang_compiler::{ - compile_prepared_db, db::RootDatabase, project::setup_project, CompilerConfig, -}; -use cairo_lang_sierra::program::Program; -use clap::{Parser, ValueHint}; -use serde::Serialize; - -#[derive(Parser, Debug)] -struct CompileArgs { - #[clap(value_parser, value_hint=ValueHint::FilePath, value_name = "FILE")] - program: PathBuf, - #[clap(short, long, value_name = "FILE")] - output: Option, -} - -#[derive(Parser, Debug)] -struct MergeArgs { - #[clap(value_parser, value_hint=ValueHint::FilePath, value_name = "FILE")] - sierra: PathBuf, - #[clap(value_parser, value_hint=ValueHint::FilePath, value_name = "FILE")] - input: PathBuf, - #[clap(short, long, value_name = "FILE")] - output: Option, - #[clap(short, long, value_enum)] - layout: Option, -} - -#[derive(clap::ValueEnum, Clone, Debug, Default)] -enum Layout { - #[default] - Recursive, -} - -#[derive(Parser, Debug)] -#[clap(author, version, about, long_about = None)] -enum Args { - Compile(CompileArgs), - Merge(MergeArgs), -} - -fn main() { - match Args::parse() { - Args::Compile(args) => compile(args), - Args::Merge(args) => merge(args), - } -} - -#[derive(Debug, Clone, Serialize)] -struct ProgramWithArgs { - program: Program, - program_input: serde_json::Value, - layout: String, -} - -fn merge(args: MergeArgs) { - let sierra_program: Program = - serde_json::from_reader(BufReader::new(File::open(args.sierra).unwrap())).unwrap(); - let input: serde_json::Value = - serde_json::from_reader(BufReader::new(File::open(args.input).unwrap())).unwrap(); - - let layout = args.layout.unwrap_or(Layout::Recursive); - let merged = serde_json::to_string(&ProgramWithArgs { - program: sierra_program, - program_input: input, - layout: layout.to_string(), - }) - .unwrap(); - match args.output { - Some(output) => { - let mut file = std::fs::File::create(output).unwrap(); - file.write_all(merged.as_bytes()).unwrap(); - } - None => { - println!("{}", merged) - } - } -} - -fn compile(args: CompileArgs) { - let program = compile_sierra(&args.program); - let json_program = serde_json::to_string(&program).unwrap(); - match args.output { - Some(output) => { - let mut file = std::fs::File::create(output).unwrap(); - file.write_all(json_program.as_bytes()).unwrap(); - } - None => { - println!("{}", json_program) - } - } -} - -fn compile_sierra(filename: &Path) -> Program { - let compiler_config = CompilerConfig { - replace_ids: true, - ..CompilerConfig::default() - }; - let mut db = RootDatabase::builder() - .detect_corelib() - .skip_auto_withdraw_gas() - .build() - .unwrap(); - let main_crate_ids = setup_project(&mut db, filename).unwrap(); - compile_prepared_db(&mut db, main_crate_ids, compiler_config) - .unwrap() - .program -} - -impl fmt::Display for Layout { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Layout::Recursive => write!(f, "recursive"), - } - } -} diff --git a/crates/common/Cargo.toml b/common/Cargo.toml similarity index 84% rename from crates/common/Cargo.toml rename to common/Cargo.toml index 4a71822..da62784 100644 --- a/crates/common/Cargo.toml +++ b/common/Cargo.toml @@ -4,8 +4,8 @@ version.workspace = true edition.workspace = true [dependencies] -ed25519-dalek.workspace = true -prefix-hex.workspace = true serde_json.workspace = true -serde_with.workspace = true serde.workspace = true +serde_with.workspace = true +ed25519-dalek.workspace = true +starknet-types-core.workspace = true \ No newline at end of file diff --git a/common/src/cairo0_prover_input.rs b/common/src/cairo0_prover_input.rs new file mode 100644 index 0000000..ae01e9d --- /dev/null +++ b/common/src/cairo0_prover_input.rs @@ -0,0 +1,30 @@ +use serde::{Deserialize, Serialize}; + +use crate::ProverInput; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct Cairo0ProverInput { + pub program: Cairo0CompiledProgram, + pub program_input: serde_json::Value, + pub layout: String, +} + +impl ProverInput for Cairo0ProverInput { + fn serialize(self) -> serde_json::Value { + serde_json::to_value(self).unwrap() + } +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct Cairo0CompiledProgram { + pub attributes: Vec, + pub builtins: Vec, + pub compiler_version: String, + pub data: Vec, + pub debug_info: serde_json::Value, + pub hints: serde_json::Value, + pub identifiers: serde_json::Value, + pub main_scope: String, + pub prime: String, + pub reference_manager: serde_json::Value, +} diff --git a/crates/common/src/inputs/cairo_1_prover_input.rs b/common/src/cairo_prover_input.rs similarity index 69% rename from crates/common/src/inputs/cairo_1_prover_input.rs rename to common/src/cairo_prover_input.rs index 167d20e..1ff89fe 100644 --- a/crates/common/src/inputs/cairo_1_prover_input.rs +++ b/common/src/cairo_prover_input.rs @@ -1,20 +1,21 @@ use serde::{Deserialize, Serialize}; +use starknet_types_core::felt::Felt; use crate::ProverInput; #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -pub struct Cairo1ProverInput { - pub program: Cairo1CompiledProgram, - pub program_input: serde_json::Value, +pub struct CairoProverInput { + pub program: CairoCompiledProgram, + pub program_input: Vec, pub layout: String, } -impl ProverInput for Cairo1ProverInput { +impl ProverInput for CairoProverInput { fn serialize(self) -> serde_json::Value { serde_json::to_value(self).unwrap() } } #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -pub struct Cairo1CompiledProgram { +pub struct CairoCompiledProgram { //pub version: u64, pub type_declarations: serde_json::Value, pub libfunc_declarations: serde_json::Value, diff --git a/common/src/lib.rs b/common/src/lib.rs new file mode 100644 index 0000000..57bedcf --- /dev/null +++ b/common/src/lib.rs @@ -0,0 +1,7 @@ +pub mod cairo0_prover_input; +pub mod cairo_prover_input; +pub mod models; +pub mod requests; +pub trait ProverInput { + fn serialize(self) -> serde_json::Value; +} diff --git a/common/src/models.rs b/common/src/models.rs new file mode 100644 index 0000000..ed55bc0 --- /dev/null +++ b/common/src/models.rs @@ -0,0 +1,19 @@ +use ed25519_dalek::VerifyingKey; +use serde::{Deserialize, Serialize}; +use serde_with::{serde_as, DisplayFromStr}; + +#[serde_as] +#[derive(Debug, Serialize, Deserialize)] +pub struct JWTResponse { + #[serde_as(as = "DisplayFromStr")] + pub jwt_token: String, + pub expiration: u64, + pub session_key: Option, +} +#[derive(Serialize, Deserialize, Clone)] +pub enum JobStatus { + Pending, + Running, + Completed, + Failed, +} diff --git a/crates/common/src/requests.rs b/common/src/requests.rs similarity index 54% rename from crates/common/src/requests.rs rename to common/src/requests.rs index 083661a..3c1e4bf 100644 --- a/crates/common/src/requests.rs +++ b/common/src/requests.rs @@ -2,14 +2,23 @@ use ed25519_dalek::{Signature, VerifyingKey}; use serde::{Deserialize, Serialize}; #[derive(Debug, Serialize, Deserialize)] -pub struct AddAuthorizedRequest { +pub struct ValidateSignatureRequest { pub signature: Signature, - pub authority: VerifyingKey, - pub new_key: VerifyingKey, + pub message: Message, +} +#[derive(Debug, Serialize, Deserialize)] +pub struct Message { + pub session_key: VerifyingKey, + pub nonce: String, +} +#[derive(Debug, Serialize, Deserialize)] +pub struct GenerateNonceRequest { + pub public_key: String, } #[derive(Debug, Serialize, Deserialize)] -pub struct ValidateSignatureRequest { +pub struct AddKeyRequest { pub signature: Signature, - pub public_key: VerifyingKey, + pub authority: VerifyingKey, + pub new_key: VerifyingKey, } diff --git a/crates/common/src/inputs/cairo_0_prover_input.rs b/crates/common/src/inputs/cairo_0_prover_input.rs deleted file mode 100644 index 54125c4..0000000 --- a/crates/common/src/inputs/cairo_0_prover_input.rs +++ /dev/null @@ -1,296 +0,0 @@ -use serde::{Deserialize, Serialize}; - -use crate::ProverInput; - -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -pub struct Cairo0ProverInput { - pub program: CompiledProgram, - pub program_input: serde_json::Value, - pub layout: String, -} - -impl ProverInput for Cairo0ProverInput { - fn serialize(self) -> serde_json::Value { - serde_json::to_value(self).unwrap() - } -} - -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -pub struct CompiledProgram { - pub attributes: Vec, - pub builtins: Vec, - pub compiler_version: String, - pub data: Vec, - pub debug_info: serde_json::Value, - pub hints: serde_json::Value, - pub identifiers: serde_json::Value, - pub main_scope: String, - pub prime: String, - pub reference_manager: serde_json::Value, -} - -#[cfg(test)] -mod tests { - use crate::inputs::cairo_0_prover_input::{Cairo0ProverInput, CompiledProgram}; - - #[test] - fn test_deserialize_compiled_program() -> serde_json::Result<()> { - let input = r#"{ - "attributes": [], - "builtins": [ - "output", - "pedersen" - ], - "compiler_version": "0.13.1", - "data": [ - "0x40780017fff7fff", - "0x4", - "0x800000000000011000000000000000000000000000000000000000000000000", - "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffff9", - "0x208b7fff7fff7ffe" - ], - "debug_info": { - "file_contents": { - "": "__start__:\nap += main.Args.SIZE + main.ImplicitArgs.SIZE;\ncall main;\n\n__end__:\njmp rel 0;\n" - }, - "instruction_locations": { - "0": { - "accessible_scopes": ["__main__"], - "flow_tracking_data": { - "ap_tracking": { - "group": 0, - "offset": 0 - }, - "reference_ids": {} - }, - "hints": [], - "inst": { - "end_col": 46, - "end_line": 2, - "input_file": { - "filename": "" - }, - "start_col": 1, - "start_line": 2 - } - } - } - }, - "hints": [], - "identifiers": { - "__main__.__end__": { - "pc": 4, - "type": "label" - }, - "__main__.__start__": { - "pc": 0, - "type": "label" - } - }, - "main_scope": "__main__", - "prime": "0x800000000000011000000000000000000000000000000000000000000000001", - "reference_manager": { - "references": [] - } - }"#; - - let compiled_program = serde_json::from_str::(input)?; - let expected = CompiledProgram { - attributes: vec![], - builtins: vec!["output".to_string(), "pedersen".to_string()], - compiler_version: "0.13.1".to_string(), - data: vec![ - "0x40780017fff7fff".to_string(), - "0x4".to_string(), - "0x800000000000011000000000000000000000000000000000000000000000000".to_string(), - "0x1104800180018000".to_string(), - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffff9".to_string(), - "0x208b7fff7fff7ffe".to_string(), - ], - debug_info: serde_json::json!({ - "file_contents": { - "": "__start__:\nap += main.Args.SIZE + main.ImplicitArgs.SIZE;\ncall main;\n\n__end__:\njmp rel 0;\n" - }, - "instruction_locations": { - "0": { - "accessible_scopes": ["__main__"], - "flow_tracking_data": { - "ap_tracking": { - "group": 0, - "offset": 0 - }, - "reference_ids": {} - }, - "hints": [], - "inst": { - "end_col": 46, - "end_line": 2, - "input_file": { - "filename": "" - }, - "start_col": 1, - "start_line": 2 - } - } - } - }), - hints: serde_json::Value::Array(Default::default()), - identifiers: serde_json::json!({ - "__main__.__end__": { - "pc": 4, - "type": "label" - }, - "__main__.__start__": { - "pc": 0, - "type": "label" - } - }), - main_scope: "__main__".to_string(), - prime: "0x800000000000011000000000000000000000000000000000000000000000001".to_string(), - reference_manager: serde_json::json!({ - "references": [] - }), - }; - - assert_eq!(compiled_program, expected); - - Ok(()) - } - - #[test] - fn test_serialize_compiled_program() -> serde_json::Result<()> { - let input = CompiledProgram { - attributes: vec![], - builtins: vec!["output".to_string(), "pedersen".to_string()], - compiler_version: "0.13.1".to_string(), - data: vec![ - "0x40780017fff7fff".to_string(), - "0x4".to_string(), - "0x800000000000011000000000000000000000000000000000000000000000000".to_string(), - "0x1104800180018000".to_string(), - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffff9".to_string(), - "0x208b7fff7fff7ffe".to_string(), - ], - debug_info: serde_json::json!({ - "file_contents": { - "": "__start__:\nap += main.Args.SIZE + main.ImplicitArgs.SIZE;\ncall main;\n\n__end__:\njmp rel 0;\n" - }, - "instruction_locations": { - "0": { - "accessible_scopes": ["__main__"], - "flow_tracking_data": { - "ap_tracking": { - "group": 0, - "offset": 0 - }, - "reference_ids": {} - }, - "hints": [], - "inst": { - "end_col": 46, - "end_line": 2, - "input_file": { - "filename": "" - }, - "start_col": 1, - "start_line": 2 - } - } - } - }), - hints: serde_json::Value::Array(Default::default()), - identifiers: serde_json::json!({ - "__main__.__end__": { - "pc": 4, - "type": "label" - }, - "__main__.__start__": { - "pc": 0, - "type": "label" - } - }), - main_scope: "__main__".to_string(), - prime: "0x800000000000011000000000000000000000000000000000000000000000001".to_string(), - reference_manager: serde_json::json!({ - "references": [] - }), - }; - let serialized = serde_json::to_string(&input)?; - let deserialized = serde_json::from_str(&serialized)?; - assert_eq!(input, deserialized); - Ok(()) - } - - #[test] - fn test_serialize_prove_input() -> serde_json::Result<()> { - let compiled_program = CompiledProgram { - attributes: vec![], - builtins: vec!["output".to_string(), "pedersen".to_string()], - compiler_version: "0.13.1".to_string(), - data: vec![ - "0x40780017fff7fff".to_string(), - "0x4".to_string(), - "0x800000000000011000000000000000000000000000000000000000000000000".to_string(), - "0x1104800180018000".to_string(), - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffff9".to_string(), - "0x208b7fff7fff7ffe".to_string(), - ], - debug_info: serde_json::json!({ - "file_contents": { - "": "__start__:\nap += main.Args.SIZE + main.ImplicitArgs.SIZE;\ncall main;\n\n__end__:\njmp rel 0;\n" - }, - "instruction_locations": { - "0": { - "accessible_scopes": ["__main__"], - "flow_tracking_data": { - "ap_tracking": { - "group": 0, - "offset": 0 - }, - "reference_ids": {} - }, - "hints": [], - "inst": { - "end_col": 46, - "end_line": 2, - "input_file": { - "filename": "" - }, - "start_col": 1, - "start_line": 2 - } - } - } - }), - hints: serde_json::Value::Array(Default::default()), - identifiers: serde_json::json!({ - "__main__.__end__": { - "pc": 4, - "type": "label" - }, - "__main__.__start__": { - "pc": 0, - "type": "label" - } - }), - main_scope: "__main__".to_string(), - prime: "0x800000000000011000000000000000000000000000000000000000000000001".to_string(), - reference_manager: serde_json::json!({ - "references": [] - }), - }; - let input = r#"{ - "fibonacci_claim_index": 10 - }"#; - let prove_input = Cairo0ProverInput { - program: compiled_program, - program_input: serde_json::to_value(input).unwrap(), - layout: "recursive".to_string(), - }; - let serialized = &serde_json::to_string(&prove_input).unwrap(); - let deserialized: Cairo0ProverInput = serde_json::from_str(serialized).unwrap(); - assert_eq!(deserialized, prove_input); - Ok(()) - } -} diff --git a/crates/common/src/inputs/mod.rs b/crates/common/src/inputs/mod.rs deleted file mode 100644 index 65b19d4..0000000 --- a/crates/common/src/inputs/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -mod cairo_0_prover_input; -mod cairo_1_prover_input; - -pub use cairo_0_prover_input::*; -pub use cairo_1_prover_input::*; diff --git a/crates/common/src/lib.rs b/crates/common/src/lib.rs deleted file mode 100644 index 0b7f278..0000000 --- a/crates/common/src/lib.rs +++ /dev/null @@ -1,11 +0,0 @@ -mod inputs; -mod models; -mod requests; - -pub use inputs::*; -pub use models::*; -pub use requests::*; - -pub trait ProverInput { - fn serialize(self) -> serde_json::Value; -} diff --git a/crates/common/src/models.rs b/crates/common/src/models.rs deleted file mode 100644 index bc99399..0000000 --- a/crates/common/src/models.rs +++ /dev/null @@ -1,23 +0,0 @@ -use serde::{Deserialize, Serialize}; -use serde_with::{serde_as, DisplayFromStr}; - -#[serde_as] -#[derive(Debug, Serialize, Deserialize)] -pub struct JWTResponse { - #[serde_as(as = "DisplayFromStr")] - pub jwt_token: String, - pub expiration: u64, -} - -#[serde_as] -#[derive(Debug, Serialize, Deserialize)] -pub struct RequestCreateContract { - pub address: String, - pub quantity: u64, - pub url_request_quote: String, - pub url_accept_contract: String, -} - -pub fn bytes_to_hex_string(bytes: &[u8]) -> String { - prefix_hex::encode(bytes) -} diff --git a/crates/utils/Cargo.toml b/crates/utils/Cargo.toml deleted file mode 100644 index 1f820b7..0000000 --- a/crates/utils/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "utils" -version.workspace = true -edition.workspace = true - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -tokio.workspace = true diff --git a/crates/utils/src/lib.rs b/crates/utils/src/lib.rs deleted file mode 100644 index 7e0cedf..0000000 --- a/crates/utils/src/lib.rs +++ /dev/null @@ -1,16 +0,0 @@ -pub mod shutdown; - -pub fn add(left: usize, right: usize) -> usize { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } -} diff --git a/crates/utils/src/shutdown.rs b/crates/utils/src/shutdown.rs deleted file mode 100644 index 6bdf658..0000000 --- a/crates/utils/src/shutdown.rs +++ /dev/null @@ -1,23 +0,0 @@ -pub async fn shutdown_signal() { - let ctrl_c = async { - tokio::signal::ctrl_c() - .await - .expect("failed to install Ctrl+C handler"); - }; - - #[cfg(unix)] - let terminate = async { - tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate()) - .expect("failed to install signal handler") - .recv() - .await; - }; - - #[cfg(not(unix))] - let terminate = std::future::pending::<()>(); - - tokio::select! { - _ = ctrl_c => {}, - _ = terminate => {}, - } -} diff --git a/examples/Cairo/fibonacci.cairo b/examples/Cairo/fibonacci.cairo deleted file mode 100644 index 425c95c..0000000 --- a/examples/Cairo/fibonacci.cairo +++ /dev/null @@ -1,13 +0,0 @@ -use core::array::ArrayTrait; -fn main(mut n: Array) -> Array { - let r = fib(n.pop_front().unwrap()); - array![r.into()] -} - -fn fib(n: felt252) -> felt252 { - if n == 1 || n == 0 { - return n; - } - - fib(n - 1) + fib(n - 2) -} \ No newline at end of file diff --git a/examples/Cairo/fibonacci_prover_input.json b/examples/Cairo/fibonacci_prover_input.json deleted file mode 100644 index 48d5084..0000000 --- a/examples/Cairo/fibonacci_prover_input.json +++ /dev/null @@ -1,1198 +0,0 @@ -{ - "program": { - "type_declarations": [ - { - "id": { "id": 1, "debug_name": "Array" }, - "long_id": { - "generic_id": "Array", - "generic_args": [{ "Type": { "id": 0, "debug_name": "felt252" } }] - }, - "declared_type_info": { - "storable": true, - "droppable": true, - "duplicatable": false, - "zero_sized": false - } - }, - { - "id": { "id": 12, "debug_name": "Const" }, - "long_id": { - "generic_id": "Const", - "generic_args": [ - { "Type": { "id": 0, "debug_name": "felt252" } }, - { "Value": [1, [2]] } - ] - }, - "declared_type_info": { - "storable": false, - "droppable": false, - "duplicatable": false, - "zero_sized": false - } - }, - { - "id": { "id": 0, "debug_name": "felt252" }, - "long_id": { "generic_id": "felt252", "generic_args": [] }, - "declared_type_info": { - "storable": true, - "droppable": true, - "duplicatable": true, - "zero_sized": false - } - }, - { - "id": { "id": 9, "debug_name": "NonZero" }, - "long_id": { - "generic_id": "NonZero", - "generic_args": [{ "Type": { "id": 0, "debug_name": "felt252" } }] - }, - "declared_type_info": { - "storable": true, - "droppable": true, - "duplicatable": true, - "zero_sized": false - } - }, - { - "id": { "id": 10, "debug_name": "Const" }, - "long_id": { - "generic_id": "Const", - "generic_args": [ - { "Type": { "id": 0, "debug_name": "felt252" } }, - { "Value": [1, [1]] } - ] - }, - "declared_type_info": { - "storable": false, - "droppable": false, - "duplicatable": false, - "zero_sized": false - } - }, - { - "id": { "id": 11, "debug_name": "Uninitialized" }, - "long_id": { - "generic_id": "Uninitialized", - "generic_args": [{ "Type": { "id": 0, "debug_name": "felt252" } }] - }, - "declared_type_info": { - "storable": false, - "droppable": true, - "duplicatable": false, - "zero_sized": false - } - }, - { - "id": { "id": 4, "debug_name": "core::panics::Panic" }, - "long_id": { - "generic_id": "Struct", - "generic_args": [ - { - "UserType": { - "id": [ - 2208749170, 1797821712, 129214108, 2539384922, 764199911, - 1378060934, 2080739472, 23743629 - ], - "debug_name": "core::panics::Panic" - } - } - ] - }, - "declared_type_info": { - "storable": true, - "droppable": true, - "duplicatable": true, - "zero_sized": true - } - }, - { - "id": { - "id": 5, - "debug_name": "Tuple>" - }, - "long_id": { - "generic_id": "Struct", - "generic_args": [ - { - "UserType": { - "id": [ - 1380714691, 777545161, 640624565, 3564344830, 2506258596, - 2515665124, 462026948, 49159723 - ], - "debug_name": "Tuple" - } - }, - { "Type": { "id": 4, "debug_name": "core::panics::Panic" } }, - { "Type": { "id": 1, "debug_name": "Array" } } - ] - }, - "declared_type_info": { - "storable": true, - "droppable": true, - "duplicatable": false, - "zero_sized": false - } - }, - { - "id": { - "id": 7, - "debug_name": "Const" - }, - "long_id": { - "generic_id": "Const", - "generic_args": [ - { "Type": { "id": 0, "debug_name": "felt252" } }, - { - "Value": [ - 1, - [ - 1818584110, 543580521, 2003984752, 976909678, 1953066862, - 20336 - ] - ] - } - ] - }, - "declared_type_info": { - "storable": false, - "droppable": false, - "duplicatable": false, - "zero_sized": false - } - }, - { - "id": { "id": 3, "debug_name": "Tuple>" }, - "long_id": { - "generic_id": "Struct", - "generic_args": [ - { - "UserType": { - "id": [ - 1380714691, 777545161, 640624565, 3564344830, 2506258596, - 2515665124, 462026948, 49159723 - ], - "debug_name": "Tuple" - } - }, - { "Type": { "id": 1, "debug_name": "Array" } } - ] - }, - "declared_type_info": { - "storable": true, - "droppable": true, - "duplicatable": false, - "zero_sized": false - } - }, - { - "id": { - "id": 6, - "debug_name": "core::panics::PanicResult::<(core::array::Array::,)>" - }, - "long_id": { - "generic_id": "Enum", - "generic_args": [ - { - "UserType": { - "id": [ - 704622403, 483171566, 1759595788, 2942942373, 3836427357, - 911959852, 2124004651, 45932020 - ], - "debug_name": "core::panics::PanicResult::<(core::array::Array::,)>" - } - }, - { "Type": { "id": 3, "debug_name": "Tuple>" } }, - { - "Type": { - "id": 5, - "debug_name": "Tuple>" - } - } - ] - }, - "declared_type_info": { - "storable": true, - "droppable": true, - "duplicatable": false, - "zero_sized": false - } - }, - { - "id": { "id": 2, "debug_name": "Box" }, - "long_id": { - "generic_id": "Box", - "generic_args": [{ "Type": { "id": 0, "debug_name": "felt252" } }] - }, - "declared_type_info": { - "storable": true, - "droppable": true, - "duplicatable": true, - "zero_sized": false - } - } - ], - "libfunc_declarations": [ - { - "id": { "id": 10, "debug_name": "disable_ap_tracking" }, - "long_id": { "generic_id": "disable_ap_tracking", "generic_args": [] } - }, - { - "id": { "id": 9, "debug_name": "array_pop_front" }, - "long_id": { - "generic_id": "array_pop_front", - "generic_args": [{ "Type": { "id": 0, "debug_name": "felt252" } }] - } - }, - { - "id": { "id": 11, "debug_name": "branch_align" }, - "long_id": { "generic_id": "branch_align", "generic_args": [] } - }, - { - "id": { "id": 12, "debug_name": "drop>" }, - "long_id": { - "generic_id": "drop", - "generic_args": [ - { "Type": { "id": 1, "debug_name": "Array" } } - ] - } - }, - { - "id": { "id": 8, "debug_name": "unbox" }, - "long_id": { - "generic_id": "unbox", - "generic_args": [{ "Type": { "id": 0, "debug_name": "felt252" } }] - } - }, - { - "id": { "id": 14, "debug_name": "store_temp" }, - "long_id": { - "generic_id": "store_temp", - "generic_args": [{ "Type": { "id": 0, "debug_name": "felt252" } }] - } - }, - { - "id": { - "id": 7, - "debug_name": "function_call" - }, - "long_id": { - "generic_id": "function_call", - "generic_args": [ - { - "UserFunc": { "id": 0, "debug_name": "fibonacci::fibonacci::fib" } - } - ] - } - }, - { - "id": { "id": 4, "debug_name": "array_new" }, - "long_id": { - "generic_id": "array_new", - "generic_args": [{ "Type": { "id": 0, "debug_name": "felt252" } }] - } - }, - { - "id": { "id": 3, "debug_name": "array_append" }, - "long_id": { - "generic_id": "array_append", - "generic_args": [{ "Type": { "id": 0, "debug_name": "felt252" } }] - } - }, - { - "id": { - "id": 6, - "debug_name": "struct_construct>>" - }, - "long_id": { - "generic_id": "struct_construct", - "generic_args": [ - { "Type": { "id": 3, "debug_name": "Tuple>" } } - ] - } - }, - { - "id": { - "id": 5, - "debug_name": "enum_init,)>, 0>" - }, - "long_id": { - "generic_id": "enum_init", - "generic_args": [ - { - "Type": { - "id": 6, - "debug_name": "core::panics::PanicResult::<(core::array::Array::,)>" - } - }, - { "Value": [0, []] } - ] - } - }, - { - "id": { - "id": 15, - "debug_name": "store_temp,)>>" - }, - "long_id": { - "generic_id": "store_temp", - "generic_args": [ - { - "Type": { - "id": 6, - "debug_name": "core::panics::PanicResult::<(core::array::Array::,)>" - } - } - ] - } - }, - { - "id": { - "id": 13, - "debug_name": "const_as_immediate>" - }, - "long_id": { - "generic_id": "const_as_immediate", - "generic_args": [ - { - "Type": { - "id": 7, - "debug_name": "Const" - } - } - ] - } - }, - { - "id": { - "id": 2, - "debug_name": "struct_construct" - }, - "long_id": { - "generic_id": "struct_construct", - "generic_args": [ - { "Type": { "id": 4, "debug_name": "core::panics::Panic" } } - ] - } - }, - { - "id": { - "id": 1, - "debug_name": "struct_construct>>" - }, - "long_id": { - "generic_id": "struct_construct", - "generic_args": [ - { - "Type": { - "id": 5, - "debug_name": "Tuple>" - } - } - ] - } - }, - { - "id": { - "id": 0, - "debug_name": "enum_init,)>, 1>" - }, - "long_id": { - "generic_id": "enum_init", - "generic_args": [ - { - "Type": { - "id": 6, - "debug_name": "core::panics::PanicResult::<(core::array::Array::,)>" - } - }, - { "Value": [1, [1]] } - ] - } - }, - { - "id": { "id": 19, "debug_name": "alloc_local" }, - "long_id": { - "generic_id": "alloc_local", - "generic_args": [{ "Type": { "id": 0, "debug_name": "felt252" } }] - } - }, - { - "id": { "id": 20, "debug_name": "finalize_locals" }, - "long_id": { "generic_id": "finalize_locals", "generic_args": [] } - }, - { - "id": { - "id": 21, - "debug_name": "const_as_immediate>" - }, - "long_id": { - "generic_id": "const_as_immediate", - "generic_args": [ - { "Type": { "id": 10, "debug_name": "Const" } } - ] - } - }, - { - "id": { "id": 22, "debug_name": "dup" }, - "long_id": { - "generic_id": "dup", - "generic_args": [{ "Type": { "id": 0, "debug_name": "felt252" } }] - } - }, - { - "id": { "id": 17, "debug_name": "felt252_sub" }, - "long_id": { "generic_id": "felt252_sub", "generic_args": [] } - }, - { - "id": { "id": 18, "debug_name": "felt252_is_zero" }, - "long_id": { "generic_id": "felt252_is_zero", "generic_args": [] } - }, - { - "id": { "id": 23, "debug_name": "drop>" }, - "long_id": { - "generic_id": "drop", - "generic_args": [ - { "Type": { "id": 11, "debug_name": "Uninitialized" } } - ] - } - }, - { - "id": { "id": 24, "debug_name": "jump" }, - "long_id": { "generic_id": "jump", "generic_args": [] } - }, - { - "id": { "id": 25, "debug_name": "drop>" }, - "long_id": { - "generic_id": "drop", - "generic_args": [ - { "Type": { "id": 9, "debug_name": "NonZero" } } - ] - } - }, - { - "id": { - "id": 26, - "debug_name": "const_as_immediate>" - }, - "long_id": { - "generic_id": "const_as_immediate", - "generic_args": [ - { "Type": { "id": 12, "debug_name": "Const" } } - ] - } - }, - { - "id": { "id": 27, "debug_name": "store_local" }, - "long_id": { - "generic_id": "store_local", - "generic_args": [{ "Type": { "id": 0, "debug_name": "felt252" } }] - } - }, - { - "id": { "id": 16, "debug_name": "felt252_add" }, - "long_id": { "generic_id": "felt252_add", "generic_args": [] } - } - ], - "statements": [ - { - "Invocation": { - "libfunc_id": { "id": 10, "debug_name": "disable_ap_tracking" }, - "args": [], - "branches": [{ "target": "Fallthrough", "results": [] }] - } - }, - { - "Invocation": { - "libfunc_id": { "id": 9, "debug_name": "array_pop_front" }, - "args": [{ "id": 0, "debug_name": null }], - "branches": [ - { - "target": "Fallthrough", - "results": [ - { "id": 1, "debug_name": null }, - { "id": 2, "debug_name": null } - ] - }, - { - "target": { "Statement": 13 }, - "results": [{ "id": 3, "debug_name": null }] - } - ] - } - }, - { - "Invocation": { - "libfunc_id": { "id": 11, "debug_name": "branch_align" }, - "args": [], - "branches": [{ "target": "Fallthrough", "results": [] }] - } - }, - { - "Invocation": { - "libfunc_id": { "id": 12, "debug_name": "drop>" }, - "args": [{ "id": 1, "debug_name": null }], - "branches": [{ "target": "Fallthrough", "results": [] }] - } - }, - { - "Invocation": { - "libfunc_id": { "id": 8, "debug_name": "unbox" }, - "args": [{ "id": 2, "debug_name": null }], - "branches": [ - { - "target": "Fallthrough", - "results": [{ "id": 4, "debug_name": null }] - } - ] - } - }, - { - "Invocation": { - "libfunc_id": { "id": 14, "debug_name": "store_temp" }, - "args": [{ "id": 4, "debug_name": null }], - "branches": [ - { - "target": "Fallthrough", - "results": [{ "id": 4, "debug_name": null }] - } - ] - } - }, - { - "Invocation": { - "libfunc_id": { - "id": 7, - "debug_name": "function_call" - }, - "args": [{ "id": 4, "debug_name": null }], - "branches": [ - { - "target": "Fallthrough", - "results": [{ "id": 5, "debug_name": null }] - } - ] - } - }, - { - "Invocation": { - "libfunc_id": { "id": 4, "debug_name": "array_new" }, - "args": [], - "branches": [ - { - "target": "Fallthrough", - "results": [{ "id": 6, "debug_name": null }] - } - ] - } - }, - { - "Invocation": { - "libfunc_id": { "id": 3, "debug_name": "array_append" }, - "args": [ - { "id": 6, "debug_name": null }, - { "id": 5, "debug_name": null } - ], - "branches": [ - { - "target": "Fallthrough", - "results": [{ "id": 7, "debug_name": null }] - } - ] - } - }, - { - "Invocation": { - "libfunc_id": { - "id": 6, - "debug_name": "struct_construct>>" - }, - "args": [{ "id": 7, "debug_name": null }], - "branches": [ - { - "target": "Fallthrough", - "results": [{ "id": 8, "debug_name": null }] - } - ] - } - }, - { - "Invocation": { - "libfunc_id": { - "id": 5, - "debug_name": "enum_init,)>, 0>" - }, - "args": [{ "id": 8, "debug_name": null }], - "branches": [ - { - "target": "Fallthrough", - "results": [{ "id": 9, "debug_name": null }] - } - ] - } - }, - { - "Invocation": { - "libfunc_id": { - "id": 15, - "debug_name": "store_temp,)>>" - }, - "args": [{ "id": 9, "debug_name": null }], - "branches": [ - { - "target": "Fallthrough", - "results": [{ "id": 9, "debug_name": null }] - } - ] - } - }, - { "Return": [{ "id": 9, "debug_name": null }] }, - { - "Invocation": { - "libfunc_id": { "id": 11, "debug_name": "branch_align" }, - "args": [], - "branches": [{ "target": "Fallthrough", "results": [] }] - } - }, - { - "Invocation": { - "libfunc_id": { "id": 12, "debug_name": "drop>" }, - "args": [{ "id": 3, "debug_name": null }], - "branches": [{ "target": "Fallthrough", "results": [] }] - } - }, - { - "Invocation": { - "libfunc_id": { "id": 4, "debug_name": "array_new" }, - "args": [], - "branches": [ - { - "target": "Fallthrough", - "results": [{ "id": 10, "debug_name": null }] - } - ] - } - }, - { - "Invocation": { - "libfunc_id": { - "id": 13, - "debug_name": "const_as_immediate>" - }, - "args": [], - "branches": [ - { - "target": "Fallthrough", - "results": [{ "id": 11, "debug_name": null }] - } - ] - } - }, - { - "Invocation": { - "libfunc_id": { "id": 14, "debug_name": "store_temp" }, - "args": [{ "id": 11, "debug_name": null }], - "branches": [ - { - "target": "Fallthrough", - "results": [{ "id": 11, "debug_name": null }] - } - ] - } - }, - { - "Invocation": { - "libfunc_id": { "id": 3, "debug_name": "array_append" }, - "args": [ - { "id": 10, "debug_name": null }, - { "id": 11, "debug_name": null } - ], - "branches": [ - { - "target": "Fallthrough", - "results": [{ "id": 12, "debug_name": null }] - } - ] - } - }, - { - "Invocation": { - "libfunc_id": { - "id": 2, - "debug_name": "struct_construct" - }, - "args": [], - "branches": [ - { - "target": "Fallthrough", - "results": [{ "id": 13, "debug_name": null }] - } - ] - } - }, - { - "Invocation": { - "libfunc_id": { - "id": 1, - "debug_name": "struct_construct>>" - }, - "args": [ - { "id": 13, "debug_name": null }, - { "id": 12, "debug_name": null } - ], - "branches": [ - { - "target": "Fallthrough", - "results": [{ "id": 14, "debug_name": null }] - } - ] - } - }, - { - "Invocation": { - "libfunc_id": { - "id": 0, - "debug_name": "enum_init,)>, 1>" - }, - "args": [{ "id": 14, "debug_name": null }], - "branches": [ - { - "target": "Fallthrough", - "results": [{ "id": 15, "debug_name": null }] - } - ] - } - }, - { - "Invocation": { - "libfunc_id": { - "id": 15, - "debug_name": "store_temp,)>>" - }, - "args": [{ "id": 15, "debug_name": null }], - "branches": [ - { - "target": "Fallthrough", - "results": [{ "id": 15, "debug_name": null }] - } - ] - } - }, - { "Return": [{ "id": 15, "debug_name": null }] }, - { - "Invocation": { - "libfunc_id": { "id": 19, "debug_name": "alloc_local" }, - "args": [], - "branches": [ - { - "target": "Fallthrough", - "results": [{ "id": 2, "debug_name": null }] - } - ] - } - }, - { - "Invocation": { - "libfunc_id": { "id": 20, "debug_name": "finalize_locals" }, - "args": [], - "branches": [{ "target": "Fallthrough", "results": [] }] - } - }, - { - "Invocation": { - "libfunc_id": { "id": 10, "debug_name": "disable_ap_tracking" }, - "args": [], - "branches": [{ "target": "Fallthrough", "results": [] }] - } - }, - { - "Invocation": { - "libfunc_id": { - "id": 21, - "debug_name": "const_as_immediate>" - }, - "args": [], - "branches": [ - { - "target": "Fallthrough", - "results": [{ "id": 3, "debug_name": null }] - } - ] - } - }, - { - "Invocation": { - "libfunc_id": { "id": 22, "debug_name": "dup" }, - "args": [{ "id": 0, "debug_name": null }], - "branches": [ - { - "target": "Fallthrough", - "results": [ - { "id": 0, "debug_name": null }, - { "id": 4, "debug_name": null } - ] - } - ] - } - }, - { - "Invocation": { - "libfunc_id": { "id": 17, "debug_name": "felt252_sub" }, - "args": [ - { "id": 4, "debug_name": null }, - { "id": 3, "debug_name": null } - ], - "branches": [ - { - "target": "Fallthrough", - "results": [{ "id": 5, "debug_name": null }] - } - ] - } - }, - { - "Invocation": { - "libfunc_id": { "id": 14, "debug_name": "store_temp" }, - "args": [{ "id": 5, "debug_name": null }], - "branches": [ - { - "target": "Fallthrough", - "results": [{ "id": 5, "debug_name": null }] - } - ] - } - }, - { - "Invocation": { - "libfunc_id": { "id": 18, "debug_name": "felt252_is_zero" }, - "args": [{ "id": 5, "debug_name": null }], - "branches": [ - { "target": "Fallthrough", "results": [] }, - { - "target": { "Statement": 35 }, - "results": [{ "id": 6, "debug_name": null }] - } - ] - } - }, - { - "Invocation": { - "libfunc_id": { "id": 11, "debug_name": "branch_align" }, - "args": [], - "branches": [{ "target": "Fallthrough", "results": [] }] - } - }, - { - "Invocation": { - "libfunc_id": { - "id": 23, - "debug_name": "drop>" - }, - "args": [{ "id": 2, "debug_name": null }], - "branches": [{ "target": "Fallthrough", "results": [] }] - } - }, - { - "Invocation": { - "libfunc_id": { "id": 24, "debug_name": "jump" }, - "args": [], - "branches": [{ "target": { "Statement": 41 }, "results": [] }] - } - }, - { - "Invocation": { - "libfunc_id": { "id": 11, "debug_name": "branch_align" }, - "args": [], - "branches": [{ "target": "Fallthrough", "results": [] }] - } - }, - { - "Invocation": { - "libfunc_id": { "id": 25, "debug_name": "drop>" }, - "args": [{ "id": 6, "debug_name": null }], - "branches": [{ "target": "Fallthrough", "results": [] }] - } - }, - { - "Invocation": { - "libfunc_id": { "id": 22, "debug_name": "dup" }, - "args": [{ "id": 0, "debug_name": null }], - "branches": [ - { - "target": "Fallthrough", - "results": [ - { "id": 0, "debug_name": null }, - { "id": 7, "debug_name": null } - ] - } - ] - } - }, - { - "Invocation": { - "libfunc_id": { "id": 18, "debug_name": "felt252_is_zero" }, - "args": [{ "id": 7, "debug_name": null }], - "branches": [ - { "target": "Fallthrough", "results": [] }, - { - "target": { "Statement": 43 }, - "results": [{ "id": 8, "debug_name": null }] - } - ] - } - }, - { - "Invocation": { - "libfunc_id": { "id": 11, "debug_name": "branch_align" }, - "args": [], - "branches": [{ "target": "Fallthrough", "results": [] }] - } - }, - { - "Invocation": { - "libfunc_id": { - "id": 23, - "debug_name": "drop>" - }, - "args": [{ "id": 2, "debug_name": null }], - "branches": [{ "target": "Fallthrough", "results": [] }] - } - }, - { - "Invocation": { - "libfunc_id": { "id": 14, "debug_name": "store_temp" }, - "args": [{ "id": 0, "debug_name": null }], - "branches": [ - { - "target": "Fallthrough", - "results": [{ "id": 0, "debug_name": null }] - } - ] - } - }, - { "Return": [{ "id": 0, "debug_name": null }] }, - { - "Invocation": { - "libfunc_id": { "id": 11, "debug_name": "branch_align" }, - "args": [], - "branches": [{ "target": "Fallthrough", "results": [] }] - } - }, - { - "Invocation": { - "libfunc_id": { "id": 25, "debug_name": "drop>" }, - "args": [{ "id": 8, "debug_name": null }], - "branches": [{ "target": "Fallthrough", "results": [] }] - } - }, - { - "Invocation": { - "libfunc_id": { - "id": 21, - "debug_name": "const_as_immediate>" - }, - "args": [], - "branches": [ - { - "target": "Fallthrough", - "results": [{ "id": 9, "debug_name": null }] - } - ] - } - }, - { - "Invocation": { - "libfunc_id": { "id": 22, "debug_name": "dup" }, - "args": [{ "id": 0, "debug_name": null }], - "branches": [ - { - "target": "Fallthrough", - "results": [ - { "id": 0, "debug_name": null }, - { "id": 10, "debug_name": null } - ] - } - ] - } - }, - { - "Invocation": { - "libfunc_id": { "id": 17, "debug_name": "felt252_sub" }, - "args": [ - { "id": 10, "debug_name": null }, - { "id": 9, "debug_name": null } - ], - "branches": [ - { - "target": "Fallthrough", - "results": [{ "id": 11, "debug_name": null }] - } - ] - } - }, - { - "Invocation": { - "libfunc_id": { "id": 14, "debug_name": "store_temp" }, - "args": [{ "id": 11, "debug_name": null }], - "branches": [ - { - "target": "Fallthrough", - "results": [{ "id": 11, "debug_name": null }] - } - ] - } - }, - { - "Invocation": { - "libfunc_id": { - "id": 7, - "debug_name": "function_call" - }, - "args": [{ "id": 11, "debug_name": null }], - "branches": [ - { - "target": "Fallthrough", - "results": [{ "id": 1, "debug_name": null }] - } - ] - } - }, - { - "Invocation": { - "libfunc_id": { - "id": 26, - "debug_name": "const_as_immediate>" - }, - "args": [], - "branches": [ - { - "target": "Fallthrough", - "results": [{ "id": 12, "debug_name": null }] - } - ] - } - }, - { - "Invocation": { - "libfunc_id": { "id": 17, "debug_name": "felt252_sub" }, - "args": [ - { "id": 0, "debug_name": null }, - { "id": 12, "debug_name": null } - ], - "branches": [ - { - "target": "Fallthrough", - "results": [{ "id": 13, "debug_name": null }] - } - ] - } - }, - { - "Invocation": { - "libfunc_id": { "id": 14, "debug_name": "store_temp" }, - "args": [{ "id": 13, "debug_name": null }], - "branches": [ - { - "target": "Fallthrough", - "results": [{ "id": 13, "debug_name": null }] - } - ] - } - }, - { - "Invocation": { - "libfunc_id": { "id": 27, "debug_name": "store_local" }, - "args": [ - { "id": 2, "debug_name": null }, - { "id": 1, "debug_name": null } - ], - "branches": [ - { - "target": "Fallthrough", - "results": [{ "id": 1, "debug_name": null }] - } - ] - } - }, - { - "Invocation": { - "libfunc_id": { - "id": 7, - "debug_name": "function_call" - }, - "args": [{ "id": 13, "debug_name": null }], - "branches": [ - { - "target": "Fallthrough", - "results": [{ "id": 14, "debug_name": null }] - } - ] - } - }, - { - "Invocation": { - "libfunc_id": { "id": 16, "debug_name": "felt252_add" }, - "args": [ - { "id": 1, "debug_name": null }, - { "id": 14, "debug_name": null } - ], - "branches": [ - { - "target": "Fallthrough", - "results": [{ "id": 15, "debug_name": null }] - } - ] - } - }, - { - "Invocation": { - "libfunc_id": { "id": 14, "debug_name": "store_temp" }, - "args": [{ "id": 15, "debug_name": null }], - "branches": [ - { - "target": "Fallthrough", - "results": [{ "id": 15, "debug_name": null }] - } - ] - } - }, - { "Return": [{ "id": 15, "debug_name": null }] } - ], - "funcs": [ - { - "id": { "id": 1, "debug_name": "fibonacci::fibonacci::main" }, - "signature": { - "param_types": [{ "id": 1, "debug_name": "Array" }], - "ret_types": [ - { - "id": 6, - "debug_name": "core::panics::PanicResult::<(core::array::Array::,)>" - } - ] - }, - "params": [ - { - "id": { "id": 0, "debug_name": null }, - "ty": { "id": 1, "debug_name": "Array" } - } - ], - "entry_point": 0 - }, - { - "id": { "id": 0, "debug_name": "fibonacci::fibonacci::fib" }, - "signature": { - "param_types": [{ "id": 0, "debug_name": "felt252" }], - "ret_types": [{ "id": 0, "debug_name": "felt252" }] - }, - "params": [ - { - "id": { "id": 0, "debug_name": null }, - "ty": { "id": 0, "debug_name": "felt252" } - } - ], - "entry_point": 24 - } - ] - }, - "program_input": ["[10]"], - "layout": "recursive" -} diff --git a/examples/Cairo/input.json b/examples/Cairo/input.json deleted file mode 100644 index ed14265..0000000 --- a/examples/Cairo/input.json +++ /dev/null @@ -1 +0,0 @@ -["[10]"] \ No newline at end of file diff --git a/examples/cairo/fibonacci_compiled.json b/examples/cairo/fibonacci_compiled.json new file mode 100644 index 0000000..624c386 --- /dev/null +++ b/examples/cairo/fibonacci_compiled.json @@ -0,0 +1,2167 @@ +{ + "version": 1, + "type_declarations": [ + { + "id": { + "id": 1, + "debug_name": "Array" + }, + "long_id": { + "generic_id": "Array", + "generic_args": [ + { + "Type": { + "id": 0, + "debug_name": "felt252" + } + } + ] + }, + "declared_type_info": { + "storable": true, + "droppable": true, + "duplicatable": false, + "zero_sized": false + } + }, + { + "id": { + "id": 12, + "debug_name": "Const" + }, + "long_id": { + "generic_id": "Const", + "generic_args": [ + { + "Type": { + "id": 0, + "debug_name": "felt252" + } + }, + { + "Value": [ + 1, + [ + 2 + ] + ] + } + ] + }, + "declared_type_info": { + "storable": false, + "droppable": false, + "duplicatable": false, + "zero_sized": false + } + }, + { + "id": { + "id": 0, + "debug_name": "felt252" + }, + "long_id": { + "generic_id": "felt252", + "generic_args": [] + }, + "declared_type_info": { + "storable": true, + "droppable": true, + "duplicatable": true, + "zero_sized": false + } + }, + { + "id": { + "id": 9, + "debug_name": "NonZero" + }, + "long_id": { + "generic_id": "NonZero", + "generic_args": [ + { + "Type": { + "id": 0, + "debug_name": "felt252" + } + } + ] + }, + "declared_type_info": { + "storable": true, + "droppable": true, + "duplicatable": true, + "zero_sized": false + } + }, + { + "id": { + "id": 10, + "debug_name": "Const" + }, + "long_id": { + "generic_id": "Const", + "generic_args": [ + { + "Type": { + "id": 0, + "debug_name": "felt252" + } + }, + { + "Value": [ + 1, + [ + 1 + ] + ] + } + ] + }, + "declared_type_info": { + "storable": false, + "droppable": false, + "duplicatable": false, + "zero_sized": false + } + }, + { + "id": { + "id": 11, + "debug_name": "Uninitialized" + }, + "long_id": { + "generic_id": "Uninitialized", + "generic_args": [ + { + "Type": { + "id": 0, + "debug_name": "felt252" + } + } + ] + }, + "declared_type_info": { + "storable": false, + "droppable": true, + "duplicatable": false, + "zero_sized": false + } + }, + { + "id": { + "id": 4, + "debug_name": "core::panics::Panic" + }, + "long_id": { + "generic_id": "Struct", + "generic_args": [ + { + "UserType": { + "id": [ + 2208749170, + 1797821712, + 129214108, + 2539384922, + 764199911, + 1378060934, + 2080739472, + 23743629 + ], + "debug_name": "core::panics::Panic" + } + } + ] + }, + "declared_type_info": { + "storable": true, + "droppable": true, + "duplicatable": true, + "zero_sized": true + } + }, + { + "id": { + "id": 5, + "debug_name": "Tuple>" + }, + "long_id": { + "generic_id": "Struct", + "generic_args": [ + { + "UserType": { + "id": [ + 1380714691, + 777545161, + 640624565, + 3564344830, + 2506258596, + 2515665124, + 462026948, + 49159723 + ], + "debug_name": "Tuple" + } + }, + { + "Type": { + "id": 4, + "debug_name": "core::panics::Panic" + } + }, + { + "Type": { + "id": 1, + "debug_name": "Array" + } + } + ] + }, + "declared_type_info": { + "storable": true, + "droppable": true, + "duplicatable": false, + "zero_sized": false + } + }, + { + "id": { + "id": 7, + "debug_name": "Const" + }, + "long_id": { + "generic_id": "Const", + "generic_args": [ + { + "Type": { + "id": 0, + "debug_name": "felt252" + } + }, + { + "Value": [ + 1, + [ + 1818584110, + 543580521, + 2003984752, + 976909678, + 1953066862, + 20336 + ] + ] + } + ] + }, + "declared_type_info": { + "storable": false, + "droppable": false, + "duplicatable": false, + "zero_sized": false + } + }, + { + "id": { + "id": 3, + "debug_name": "Tuple>" + }, + "long_id": { + "generic_id": "Struct", + "generic_args": [ + { + "UserType": { + "id": [ + 1380714691, + 777545161, + 640624565, + 3564344830, + 2506258596, + 2515665124, + 462026948, + 49159723 + ], + "debug_name": "Tuple" + } + }, + { + "Type": { + "id": 1, + "debug_name": "Array" + } + } + ] + }, + "declared_type_info": { + "storable": true, + "droppable": true, + "duplicatable": false, + "zero_sized": false + } + }, + { + "id": { + "id": 6, + "debug_name": "core::panics::PanicResult::<(core::array::Array::,)>" + }, + "long_id": { + "generic_id": "Enum", + "generic_args": [ + { + "UserType": { + "id": [ + 704622403, + 483171566, + 1759595788, + 2942942373, + 3836427357, + 911959852, + 2124004651, + 45932020 + ], + "debug_name": "core::panics::PanicResult::<(core::array::Array::,)>" + } + }, + { + "Type": { + "id": 3, + "debug_name": "Tuple>" + } + }, + { + "Type": { + "id": 5, + "debug_name": "Tuple>" + } + } + ] + }, + "declared_type_info": { + "storable": true, + "droppable": true, + "duplicatable": false, + "zero_sized": false + } + }, + { + "id": { + "id": 2, + "debug_name": "Box" + }, + "long_id": { + "generic_id": "Box", + "generic_args": [ + { + "Type": { + "id": 0, + "debug_name": "felt252" + } + } + ] + }, + "declared_type_info": { + "storable": true, + "droppable": true, + "duplicatable": true, + "zero_sized": false + } + } + ], + "libfunc_declarations": [ + { + "id": { + "id": 10, + "debug_name": "disable_ap_tracking" + }, + "long_id": { + "generic_id": "disable_ap_tracking", + "generic_args": [] + } + }, + { + "id": { + "id": 9, + "debug_name": "array_pop_front" + }, + "long_id": { + "generic_id": "array_pop_front", + "generic_args": [ + { + "Type": { + "id": 0, + "debug_name": "felt252" + } + } + ] + } + }, + { + "id": { + "id": 11, + "debug_name": "branch_align" + }, + "long_id": { + "generic_id": "branch_align", + "generic_args": [] + } + }, + { + "id": { + "id": 12, + "debug_name": "drop>" + }, + "long_id": { + "generic_id": "drop", + "generic_args": [ + { + "Type": { + "id": 1, + "debug_name": "Array" + } + } + ] + } + }, + { + "id": { + "id": 8, + "debug_name": "unbox" + }, + "long_id": { + "generic_id": "unbox", + "generic_args": [ + { + "Type": { + "id": 0, + "debug_name": "felt252" + } + } + ] + } + }, + { + "id": { + "id": 14, + "debug_name": "store_temp" + }, + "long_id": { + "generic_id": "store_temp", + "generic_args": [ + { + "Type": { + "id": 0, + "debug_name": "felt252" + } + } + ] + } + }, + { + "id": { + "id": 7, + "debug_name": "function_call" + }, + "long_id": { + "generic_id": "function_call", + "generic_args": [ + { + "UserFunc": { + "id": 0, + "debug_name": "fibonacci::fibonacci::fib" + } + } + ] + } + }, + { + "id": { + "id": 4, + "debug_name": "array_new" + }, + "long_id": { + "generic_id": "array_new", + "generic_args": [ + { + "Type": { + "id": 0, + "debug_name": "felt252" + } + } + ] + } + }, + { + "id": { + "id": 3, + "debug_name": "array_append" + }, + "long_id": { + "generic_id": "array_append", + "generic_args": [ + { + "Type": { + "id": 0, + "debug_name": "felt252" + } + } + ] + } + }, + { + "id": { + "id": 6, + "debug_name": "struct_construct>>" + }, + "long_id": { + "generic_id": "struct_construct", + "generic_args": [ + { + "Type": { + "id": 3, + "debug_name": "Tuple>" + } + } + ] + } + }, + { + "id": { + "id": 5, + "debug_name": "enum_init,)>, 0>" + }, + "long_id": { + "generic_id": "enum_init", + "generic_args": [ + { + "Type": { + "id": 6, + "debug_name": "core::panics::PanicResult::<(core::array::Array::,)>" + } + }, + { + "Value": [ + 0, + [] + ] + } + ] + } + }, + { + "id": { + "id": 15, + "debug_name": "store_temp,)>>" + }, + "long_id": { + "generic_id": "store_temp", + "generic_args": [ + { + "Type": { + "id": 6, + "debug_name": "core::panics::PanicResult::<(core::array::Array::,)>" + } + } + ] + } + }, + { + "id": { + "id": 13, + "debug_name": "const_as_immediate>" + }, + "long_id": { + "generic_id": "const_as_immediate", + "generic_args": [ + { + "Type": { + "id": 7, + "debug_name": "Const" + } + } + ] + } + }, + { + "id": { + "id": 2, + "debug_name": "struct_construct" + }, + "long_id": { + "generic_id": "struct_construct", + "generic_args": [ + { + "Type": { + "id": 4, + "debug_name": "core::panics::Panic" + } + } + ] + } + }, + { + "id": { + "id": 1, + "debug_name": "struct_construct>>" + }, + "long_id": { + "generic_id": "struct_construct", + "generic_args": [ + { + "Type": { + "id": 5, + "debug_name": "Tuple>" + } + } + ] + } + }, + { + "id": { + "id": 0, + "debug_name": "enum_init,)>, 1>" + }, + "long_id": { + "generic_id": "enum_init", + "generic_args": [ + { + "Type": { + "id": 6, + "debug_name": "core::panics::PanicResult::<(core::array::Array::,)>" + } + }, + { + "Value": [ + 1, + [ + 1 + ] + ] + } + ] + } + }, + { + "id": { + "id": 19, + "debug_name": "alloc_local" + }, + "long_id": { + "generic_id": "alloc_local", + "generic_args": [ + { + "Type": { + "id": 0, + "debug_name": "felt252" + } + } + ] + } + }, + { + "id": { + "id": 20, + "debug_name": "finalize_locals" + }, + "long_id": { + "generic_id": "finalize_locals", + "generic_args": [] + } + }, + { + "id": { + "id": 21, + "debug_name": "const_as_immediate>" + }, + "long_id": { + "generic_id": "const_as_immediate", + "generic_args": [ + { + "Type": { + "id": 10, + "debug_name": "Const" + } + } + ] + } + }, + { + "id": { + "id": 22, + "debug_name": "dup" + }, + "long_id": { + "generic_id": "dup", + "generic_args": [ + { + "Type": { + "id": 0, + "debug_name": "felt252" + } + } + ] + } + }, + { + "id": { + "id": 17, + "debug_name": "felt252_sub" + }, + "long_id": { + "generic_id": "felt252_sub", + "generic_args": [] + } + }, + { + "id": { + "id": 18, + "debug_name": "felt252_is_zero" + }, + "long_id": { + "generic_id": "felt252_is_zero", + "generic_args": [] + } + }, + { + "id": { + "id": 23, + "debug_name": "drop>" + }, + "long_id": { + "generic_id": "drop", + "generic_args": [ + { + "Type": { + "id": 11, + "debug_name": "Uninitialized" + } + } + ] + } + }, + { + "id": { + "id": 24, + "debug_name": "jump" + }, + "long_id": { + "generic_id": "jump", + "generic_args": [] + } + }, + { + "id": { + "id": 25, + "debug_name": "drop>" + }, + "long_id": { + "generic_id": "drop", + "generic_args": [ + { + "Type": { + "id": 9, + "debug_name": "NonZero" + } + } + ] + } + }, + { + "id": { + "id": 26, + "debug_name": "const_as_immediate>" + }, + "long_id": { + "generic_id": "const_as_immediate", + "generic_args": [ + { + "Type": { + "id": 12, + "debug_name": "Const" + } + } + ] + } + }, + { + "id": { + "id": 27, + "debug_name": "store_local" + }, + "long_id": { + "generic_id": "store_local", + "generic_args": [ + { + "Type": { + "id": 0, + "debug_name": "felt252" + } + } + ] + } + }, + { + "id": { + "id": 16, + "debug_name": "felt252_add" + }, + "long_id": { + "generic_id": "felt252_add", + "generic_args": [] + } + } + ], + "statements": [ + { + "Invocation": { + "libfunc_id": { + "id": 10, + "debug_name": "disable_ap_tracking" + }, + "args": [], + "branches": [ + { + "target": "Fallthrough", + "results": [] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 9, + "debug_name": "array_pop_front" + }, + "args": [ + { + "id": 0, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 1, + "debug_name": null + }, + { + "id": 2, + "debug_name": null + } + ] + }, + { + "target": { + "Statement": 13 + }, + "results": [ + { + "id": 3, + "debug_name": null + } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 11, + "debug_name": "branch_align" + }, + "args": [], + "branches": [ + { + "target": "Fallthrough", + "results": [] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 12, + "debug_name": "drop>" + }, + "args": [ + { + "id": 1, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 8, + "debug_name": "unbox" + }, + "args": [ + { + "id": 2, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 4, + "debug_name": null + } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 14, + "debug_name": "store_temp" + }, + "args": [ + { + "id": 4, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 4, + "debug_name": null + } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 7, + "debug_name": "function_call" + }, + "args": [ + { + "id": 4, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 5, + "debug_name": null + } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 4, + "debug_name": "array_new" + }, + "args": [], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 6, + "debug_name": null + } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 3, + "debug_name": "array_append" + }, + "args": [ + { + "id": 6, + "debug_name": null + }, + { + "id": 5, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 7, + "debug_name": null + } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 6, + "debug_name": "struct_construct>>" + }, + "args": [ + { + "id": 7, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 8, + "debug_name": null + } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 5, + "debug_name": "enum_init,)>, 0>" + }, + "args": [ + { + "id": 8, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 9, + "debug_name": null + } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 15, + "debug_name": "store_temp,)>>" + }, + "args": [ + { + "id": 9, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 9, + "debug_name": null + } + ] + } + ] + } + }, + { + "Return": [ + { + "id": 9, + "debug_name": null + } + ] + }, + { + "Invocation": { + "libfunc_id": { + "id": 11, + "debug_name": "branch_align" + }, + "args": [], + "branches": [ + { + "target": "Fallthrough", + "results": [] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 12, + "debug_name": "drop>" + }, + "args": [ + { + "id": 3, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 4, + "debug_name": "array_new" + }, + "args": [], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 10, + "debug_name": null + } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 13, + "debug_name": "const_as_immediate>" + }, + "args": [], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 11, + "debug_name": null + } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 14, + "debug_name": "store_temp" + }, + "args": [ + { + "id": 11, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 11, + "debug_name": null + } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 3, + "debug_name": "array_append" + }, + "args": [ + { + "id": 10, + "debug_name": null + }, + { + "id": 11, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 12, + "debug_name": null + } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 2, + "debug_name": "struct_construct" + }, + "args": [], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 13, + "debug_name": null + } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 1, + "debug_name": "struct_construct>>" + }, + "args": [ + { + "id": 13, + "debug_name": null + }, + { + "id": 12, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 14, + "debug_name": null + } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 0, + "debug_name": "enum_init,)>, 1>" + }, + "args": [ + { + "id": 14, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 15, + "debug_name": null + } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 15, + "debug_name": "store_temp,)>>" + }, + "args": [ + { + "id": 15, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 15, + "debug_name": null + } + ] + } + ] + } + }, + { + "Return": [ + { + "id": 15, + "debug_name": null + } + ] + }, + { + "Invocation": { + "libfunc_id": { + "id": 19, + "debug_name": "alloc_local" + }, + "args": [], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 2, + "debug_name": null + } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 20, + "debug_name": "finalize_locals" + }, + "args": [], + "branches": [ + { + "target": "Fallthrough", + "results": [] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 10, + "debug_name": "disable_ap_tracking" + }, + "args": [], + "branches": [ + { + "target": "Fallthrough", + "results": [] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 21, + "debug_name": "const_as_immediate>" + }, + "args": [], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 3, + "debug_name": null + } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 22, + "debug_name": "dup" + }, + "args": [ + { + "id": 0, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 0, + "debug_name": null + }, + { + "id": 4, + "debug_name": null + } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 17, + "debug_name": "felt252_sub" + }, + "args": [ + { + "id": 4, + "debug_name": null + }, + { + "id": 3, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 5, + "debug_name": null + } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 14, + "debug_name": "store_temp" + }, + "args": [ + { + "id": 5, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 5, + "debug_name": null + } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 18, + "debug_name": "felt252_is_zero" + }, + "args": [ + { + "id": 5, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [] + }, + { + "target": { + "Statement": 35 + }, + "results": [ + { + "id": 6, + "debug_name": null + } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 11, + "debug_name": "branch_align" + }, + "args": [], + "branches": [ + { + "target": "Fallthrough", + "results": [] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 23, + "debug_name": "drop>" + }, + "args": [ + { + "id": 2, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 24, + "debug_name": "jump" + }, + "args": [], + "branches": [ + { + "target": { + "Statement": 41 + }, + "results": [] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 11, + "debug_name": "branch_align" + }, + "args": [], + "branches": [ + { + "target": "Fallthrough", + "results": [] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 25, + "debug_name": "drop>" + }, + "args": [ + { + "id": 6, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 22, + "debug_name": "dup" + }, + "args": [ + { + "id": 0, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 0, + "debug_name": null + }, + { + "id": 7, + "debug_name": null + } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 18, + "debug_name": "felt252_is_zero" + }, + "args": [ + { + "id": 7, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [] + }, + { + "target": { + "Statement": 43 + }, + "results": [ + { + "id": 8, + "debug_name": null + } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 11, + "debug_name": "branch_align" + }, + "args": [], + "branches": [ + { + "target": "Fallthrough", + "results": [] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 23, + "debug_name": "drop>" + }, + "args": [ + { + "id": 2, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 14, + "debug_name": "store_temp" + }, + "args": [ + { + "id": 0, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 0, + "debug_name": null + } + ] + } + ] + } + }, + { + "Return": [ + { + "id": 0, + "debug_name": null + } + ] + }, + { + "Invocation": { + "libfunc_id": { + "id": 11, + "debug_name": "branch_align" + }, + "args": [], + "branches": [ + { + "target": "Fallthrough", + "results": [] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 25, + "debug_name": "drop>" + }, + "args": [ + { + "id": 8, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 21, + "debug_name": "const_as_immediate>" + }, + "args": [], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 9, + "debug_name": null + } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 22, + "debug_name": "dup" + }, + "args": [ + { + "id": 0, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 0, + "debug_name": null + }, + { + "id": 10, + "debug_name": null + } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 17, + "debug_name": "felt252_sub" + }, + "args": [ + { + "id": 10, + "debug_name": null + }, + { + "id": 9, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 11, + "debug_name": null + } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 14, + "debug_name": "store_temp" + }, + "args": [ + { + "id": 11, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 11, + "debug_name": null + } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 7, + "debug_name": "function_call" + }, + "args": [ + { + "id": 11, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 1, + "debug_name": null + } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 26, + "debug_name": "const_as_immediate>" + }, + "args": [], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 12, + "debug_name": null + } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 17, + "debug_name": "felt252_sub" + }, + "args": [ + { + "id": 0, + "debug_name": null + }, + { + "id": 12, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 13, + "debug_name": null + } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 14, + "debug_name": "store_temp" + }, + "args": [ + { + "id": 13, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 13, + "debug_name": null + } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 27, + "debug_name": "store_local" + }, + "args": [ + { + "id": 2, + "debug_name": null + }, + { + "id": 1, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 1, + "debug_name": null + } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 7, + "debug_name": "function_call" + }, + "args": [ + { + "id": 13, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 14, + "debug_name": null + } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 16, + "debug_name": "felt252_add" + }, + "args": [ + { + "id": 1, + "debug_name": null + }, + { + "id": 14, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 15, + "debug_name": null + } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 14, + "debug_name": "store_temp" + }, + "args": [ + { + "id": 15, + "debug_name": null + } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { + "id": 15, + "debug_name": null + } + ] + } + ] + } + }, + { + "Return": [ + { + "id": 15, + "debug_name": null + } + ] + } + ], + "funcs": [ + { + "id": { + "id": 1, + "debug_name": "fibonacci::fibonacci::main" + }, + "signature": { + "param_types": [ + { + "id": 1, + "debug_name": "Array" + } + ], + "ret_types": [ + { + "id": 6, + "debug_name": "core::panics::PanicResult::<(core::array::Array::,)>" + } + ] + }, + "params": [ + { + "id": { + "id": 0, + "debug_name": null + }, + "ty": { + "id": 1, + "debug_name": "Array" + } + } + ], + "entry_point": 0 + }, + { + "id": { + "id": 0, + "debug_name": "fibonacci::fibonacci::fib" + }, + "signature": { + "param_types": [ + { + "id": 0, + "debug_name": "felt252" + } + ], + "ret_types": [ + { + "id": 0, + "debug_name": "felt252" + } + ] + }, + "params": [ + { + "id": { + "id": 0, + "debug_name": null + }, + "ty": { + "id": 0, + "debug_name": "felt252" + } + } + ], + "entry_point": 24 + } + ] +} diff --git a/examples/cairo/input.json b/examples/cairo/input.json new file mode 100644 index 0000000..3fde4e2 --- /dev/null +++ b/examples/cairo/input.json @@ -0,0 +1 @@ +1,2,3 \ No newline at end of file diff --git a/examples/CairoZero/fibonacci.cairo b/examples/cairo0/fibonacci.cairo similarity index 100% rename from examples/CairoZero/fibonacci.cairo rename to examples/cairo0/fibonacci.cairo diff --git a/examples/cairo0/fibonacci_compiled.json b/examples/cairo0/fibonacci_compiled.json new file mode 100644 index 0000000..5305dd9 --- /dev/null +++ b/examples/cairo0/fibonacci_compiled.json @@ -0,0 +1,1176 @@ +{ + "attributes": [], + "builtins": [ + "output", + "pedersen", + "range_check", + "bitwise" + ], + "compiler_version": "0.13.1", + "data": [ + "0x40780017fff7fff", + "0x4", + "0x1104800180018000", + "0x4", + "0x10780017fff7fff", + "0x0", + "0x40780017fff7fff", + "0x1", + "0x400380007ffa8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x1", + "0x480a80007fff8000", + "0x1104800180018000", + "0x9", + "0x400280017ffa7fff", + "0x482680017ffa8000", + "0x2", + "0x480a7ffb7fff8000", + "0x480a7ffc7fff8000", + "0x480a7ffd7fff8000", + "0x208b7fff7fff7ffe", + "0x20780017fff7ffd", + "0x4", + "0x480a7ffc7fff8000", + "0x208b7fff7fff7ffe", + "0x480a7ffc7fff8000", + "0x482a7ffc7ffb8000", + "0x482680017ffd8000", + "0x800000000000011000000000000000000000000000000000000000000000000", + "0x1104800180018000", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffff9", + "0x208b7fff7fff7ffe" + ], + "debug_info": { + "file_contents": { + "": "__start__:\nap += main.Args.SIZE + main.ImplicitArgs.SIZE;\ncall main;\n\n__end__:\njmp rel 0;\n" + }, + "instruction_locations": { + "0": { + "accessible_scopes": [ + "__main__" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 0, + "offset": 0 + }, + "reference_ids": {} + }, + "hints": [], + "inst": { + "end_col": 46, + "end_line": 2, + "input_file": { + "filename": "" + }, + "start_col": 1, + "start_line": 2 + } + }, + "2": { + "accessible_scopes": [ + "__main__" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 0, + "offset": 4 + }, + "reference_ids": {} + }, + "hints": [], + "inst": { + "end_col": 10, + "end_line": 3, + "input_file": { + "filename": "" + }, + "start_col": 1, + "start_line": 3 + } + }, + "4": { + "accessible_scopes": [ + "__main__" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 1, + "offset": 0 + }, + "reference_ids": {} + }, + "hints": [], + "inst": { + "end_col": 10, + "end_line": 6, + "input_file": { + "filename": "" + }, + "start_col": 1, + "start_line": 6 + } + }, + "6": { + "accessible_scopes": [ + "__main__", + "__main__.main" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 2, + "offset": 0 + }, + "reference_ids": { + "__main__.main.bitwise_ptr": 3, + "__main__.main.output_ptr": 0, + "__main__.main.pedersen_ptr": 1, + "__main__.main.range_check_ptr": 2 + } + }, + "hints": [], + "inst": { + "end_col": 18, + "end_line": 20, + "input_file": { + "filename": "examples/CairoZero/fibonacci.cairo" + }, + "start_col": 5, + "start_line": 20 + } + }, + "8": { + "accessible_scopes": [ + "__main__", + "__main__.main" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 2, + "offset": 1 + }, + "reference_ids": { + "__main__.main.bitwise_ptr": 3, + "__main__.main.fibonacci_claim_index": 4, + "__main__.main.output_ptr": 0, + "__main__.main.pedersen_ptr": 1, + "__main__.main.range_check_ptr": 2 + } + }, + "hints": [ + { + "location": { + "end_col": 77, + "end_line": 24, + "input_file": { + "filename": "examples/CairoZero/fibonacci.cairo" + }, + "start_col": 5, + "start_line": 24 + }, + "n_prefix_newlines": 0 + } + ], + "inst": { + "end_col": 50, + "end_line": 26, + "input_file": { + "filename": "examples/CairoZero/fibonacci.cairo" + }, + "start_col": 5, + "start_line": 26 + } + }, + "9": { + "accessible_scopes": [ + "__main__", + "__main__.main" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 2, + "offset": 1 + }, + "reference_ids": { + "__main__.main.bitwise_ptr": 3, + "__main__.main.fibonacci_claim_index": 4, + "__main__.main.output_ptr": 0, + "__main__.main.pedersen_ptr": 1, + "__main__.main.range_check_ptr": 2 + } + }, + "hints": [], + "inst": { + "end_col": 20, + "end_line": 27, + "input_file": { + "filename": "examples/CairoZero/fibonacci.cairo" + }, + "start_col": 19, + "start_line": 27 + } + }, + "11": { + "accessible_scopes": [ + "__main__", + "__main__.main" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 2, + "offset": 2 + }, + "reference_ids": { + "__main__.main.bitwise_ptr": 3, + "__main__.main.fibonacci_claim_index": 4, + "__main__.main.output_ptr": 0, + "__main__.main.pedersen_ptr": 1, + "__main__.main.range_check_ptr": 2 + } + }, + "hints": [], + "inst": { + "end_col": 23, + "end_line": 27, + "input_file": { + "filename": "examples/CairoZero/fibonacci.cairo" + }, + "start_col": 22, + "start_line": 27 + } + }, + "13": { + "accessible_scopes": [ + "__main__", + "__main__.main" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 2, + "offset": 3 + }, + "reference_ids": { + "__main__.main.bitwise_ptr": 3, + "__main__.main.fibonacci_claim_index": 4, + "__main__.main.output_ptr": 0, + "__main__.main.pedersen_ptr": 1, + "__main__.main.range_check_ptr": 2 + } + }, + "hints": [], + "inst": { + "end_col": 32, + "end_line": 23, + "input_file": { + "filename": "examples/CairoZero/fibonacci.cairo" + }, + "parent_location": [ + { + "end_col": 46, + "end_line": 27, + "input_file": { + "filename": "examples/CairoZero/fibonacci.cairo" + }, + "start_col": 25, + "start_line": 27 + }, + "While expanding the reference 'fibonacci_claim_index' in:" + ], + "start_col": 11, + "start_line": 23 + } + }, + "14": { + "accessible_scopes": [ + "__main__", + "__main__.main" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 2, + "offset": 4 + }, + "reference_ids": { + "__main__.main.bitwise_ptr": 3, + "__main__.main.fibonacci_claim_index": 4, + "__main__.main.output_ptr": 0, + "__main__.main.pedersen_ptr": 1, + "__main__.main.range_check_ptr": 2 + } + }, + "hints": [], + "inst": { + "end_col": 47, + "end_line": 27, + "input_file": { + "filename": "examples/CairoZero/fibonacci.cairo" + }, + "start_col": 15, + "start_line": 27 + } + }, + "16": { + "accessible_scopes": [ + "__main__", + "__main__.main" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 3, + "offset": 0 + }, + "reference_ids": { + "__main__.main.bitwise_ptr": 3, + "__main__.main.fibonacci_claim_index": 4, + "__main__.main.output_ptr": 0, + "__main__.main.pedersen_ptr": 1, + "__main__.main.range_check_ptr": 2, + "__main__.main.res": 5 + } + }, + "hints": [], + "inst": { + "end_col": 32, + "end_line": 28, + "input_file": { + "filename": "examples/CairoZero/fibonacci.cairo" + }, + "start_col": 5, + "start_line": 28 + } + }, + "17": { + "accessible_scopes": [ + "__main__", + "__main__.main" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 3, + "offset": 0 + }, + "reference_ids": { + "__main__.main.bitwise_ptr": 3, + "__main__.main.fibonacci_claim_index": 4, + "__main__.main.output_ptr": 6, + "__main__.main.pedersen_ptr": 1, + "__main__.main.range_check_ptr": 2, + "__main__.main.res": 5 + } + }, + "hints": [], + "inst": { + "end_col": 36, + "end_line": 29, + "input_file": { + "filename": "examples/CairoZero/fibonacci.cairo" + }, + "parent_location": [ + { + "end_col": 22, + "end_line": 17, + "input_file": { + "filename": "examples/CairoZero/fibonacci.cairo" + }, + "parent_location": [ + { + "end_col": 15, + "end_line": 32, + "input_file": { + "filename": "examples/CairoZero/fibonacci.cairo" + }, + "start_col": 5, + "start_line": 32 + }, + "While trying to retrieve the implicit argument 'output_ptr' in:" + ], + "start_col": 5, + "start_line": 17 + }, + "While expanding the reference 'output_ptr' in:" + ], + "start_col": 22, + "start_line": 29 + } + }, + "19": { + "accessible_scopes": [ + "__main__", + "__main__.main" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 3, + "offset": 1 + }, + "reference_ids": { + "__main__.main.bitwise_ptr": 3, + "__main__.main.fibonacci_claim_index": 4, + "__main__.main.output_ptr": 6, + "__main__.main.pedersen_ptr": 1, + "__main__.main.range_check_ptr": 2, + "__main__.main.res": 5 + } + }, + "hints": [], + "inst": { + "end_col": 43, + "end_line": 17, + "input_file": { + "filename": "examples/CairoZero/fibonacci.cairo" + }, + "parent_location": [ + { + "end_col": 43, + "end_line": 17, + "input_file": { + "filename": "examples/CairoZero/fibonacci.cairo" + }, + "parent_location": [ + { + "end_col": 15, + "end_line": 32, + "input_file": { + "filename": "examples/CairoZero/fibonacci.cairo" + }, + "start_col": 5, + "start_line": 32 + }, + "While trying to retrieve the implicit argument 'pedersen_ptr' in:" + ], + "start_col": 24, + "start_line": 17 + }, + "While expanding the reference 'pedersen_ptr' in:" + ], + "start_col": 24, + "start_line": 17 + } + }, + "20": { + "accessible_scopes": [ + "__main__", + "__main__.main" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 3, + "offset": 2 + }, + "reference_ids": { + "__main__.main.bitwise_ptr": 3, + "__main__.main.fibonacci_claim_index": 4, + "__main__.main.output_ptr": 6, + "__main__.main.pedersen_ptr": 1, + "__main__.main.range_check_ptr": 2, + "__main__.main.res": 5 + } + }, + "hints": [], + "inst": { + "end_col": 27, + "end_line": 18, + "input_file": { + "filename": "examples/CairoZero/fibonacci.cairo" + }, + "parent_location": [ + { + "end_col": 27, + "end_line": 18, + "input_file": { + "filename": "examples/CairoZero/fibonacci.cairo" + }, + "parent_location": [ + { + "end_col": 15, + "end_line": 32, + "input_file": { + "filename": "examples/CairoZero/fibonacci.cairo" + }, + "start_col": 5, + "start_line": 32 + }, + "While trying to retrieve the implicit argument 'range_check_ptr' in:" + ], + "start_col": 5, + "start_line": 18 + }, + "While expanding the reference 'range_check_ptr' in:" + ], + "start_col": 5, + "start_line": 18 + } + }, + "21": { + "accessible_scopes": [ + "__main__", + "__main__.main" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 3, + "offset": 3 + }, + "reference_ids": { + "__main__.main.bitwise_ptr": 3, + "__main__.main.fibonacci_claim_index": 4, + "__main__.main.output_ptr": 6, + "__main__.main.pedersen_ptr": 1, + "__main__.main.range_check_ptr": 2, + "__main__.main.res": 5 + } + }, + "hints": [], + "inst": { + "end_col": 47, + "end_line": 18, + "input_file": { + "filename": "examples/CairoZero/fibonacci.cairo" + }, + "parent_location": [ + { + "end_col": 47, + "end_line": 18, + "input_file": { + "filename": "examples/CairoZero/fibonacci.cairo" + }, + "parent_location": [ + { + "end_col": 15, + "end_line": 32, + "input_file": { + "filename": "examples/CairoZero/fibonacci.cairo" + }, + "start_col": 5, + "start_line": 32 + }, + "While trying to retrieve the implicit argument 'bitwise_ptr' in:" + ], + "start_col": 29, + "start_line": 18 + }, + "While expanding the reference 'bitwise_ptr' in:" + ], + "start_col": 29, + "start_line": 18 + } + }, + "22": { + "accessible_scopes": [ + "__main__", + "__main__.main" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 3, + "offset": 4 + }, + "reference_ids": { + "__main__.main.bitwise_ptr": 3, + "__main__.main.fibonacci_claim_index": 4, + "__main__.main.output_ptr": 6, + "__main__.main.pedersen_ptr": 1, + "__main__.main.range_check_ptr": 2, + "__main__.main.res": 5 + } + }, + "hints": [], + "inst": { + "end_col": 15, + "end_line": 32, + "input_file": { + "filename": "examples/CairoZero/fibonacci.cairo" + }, + "start_col": 5, + "start_line": 32 + } + }, + "23": { + "accessible_scopes": [ + "__main__", + "__main__.fib" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 4, + "offset": 0 + }, + "reference_ids": { + "__main__.fib.first_element": 7, + "__main__.fib.n": 9, + "__main__.fib.second_element": 8 + } + }, + "hints": [], + "inst": { + "end_col": 7, + "end_line": 36, + "input_file": { + "filename": "examples/CairoZero/fibonacci.cairo" + }, + "start_col": 5, + "start_line": 36 + } + }, + "25": { + "accessible_scopes": [ + "__main__", + "__main__.fib" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 4, + "offset": 0 + }, + "reference_ids": { + "__main__.fib.first_element": 7, + "__main__.fib.n": 9, + "__main__.fib.second_element": 8 + } + }, + "hints": [], + "inst": { + "end_col": 51, + "end_line": 35, + "input_file": { + "filename": "examples/CairoZero/fibonacci.cairo" + }, + "parent_location": [ + { + "end_col": 30, + "end_line": 37, + "input_file": { + "filename": "examples/CairoZero/fibonacci.cairo" + }, + "start_col": 16, + "start_line": 37 + }, + "While expanding the reference 'second_element' in:" + ], + "start_col": 31, + "start_line": 35 + } + }, + "26": { + "accessible_scopes": [ + "__main__", + "__main__.fib" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 4, + "offset": 1 + }, + "reference_ids": { + "__main__.fib.first_element": 7, + "__main__.fib.n": 9, + "__main__.fib.second_element": 8 + } + }, + "hints": [], + "inst": { + "end_col": 31, + "end_line": 37, + "input_file": { + "filename": "examples/CairoZero/fibonacci.cairo" + }, + "start_col": 9, + "start_line": 37 + } + }, + "27": { + "accessible_scopes": [ + "__main__", + "__main__.fib" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 4, + "offset": 0 + }, + "reference_ids": { + "__main__.fib.first_element": 7, + "__main__.fib.n": 9, + "__main__.fib.second_element": 8 + } + }, + "hints": [], + "inst": { + "end_col": 51, + "end_line": 35, + "input_file": { + "filename": "examples/CairoZero/fibonacci.cairo" + }, + "parent_location": [ + { + "end_col": 37, + "end_line": 41, + "input_file": { + "filename": "examples/CairoZero/fibonacci.cairo" + }, + "start_col": 23, + "start_line": 41 + }, + "While expanding the reference 'second_element' in:" + ], + "start_col": 31, + "start_line": 35 + } + }, + "28": { + "accessible_scopes": [ + "__main__", + "__main__.fib" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 4, + "offset": 1 + }, + "reference_ids": { + "__main__.fib.first_element": 7, + "__main__.fib.n": 9, + "__main__.fib.second_element": 8 + } + }, + "hints": [], + "inst": { + "end_col": 84, + "end_line": 41, + "input_file": { + "filename": "examples/CairoZero/fibonacci.cairo" + }, + "start_col": 54, + "start_line": 41 + } + }, + "29": { + "accessible_scopes": [ + "__main__", + "__main__.fib" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 4, + "offset": 2 + }, + "reference_ids": { + "__main__.fib.first_element": 7, + "__main__.fib.n": 9, + "__main__.fib.second_element": 8 + } + }, + "hints": [], + "inst": { + "end_col": 93, + "end_line": 41, + "input_file": { + "filename": "examples/CairoZero/fibonacci.cairo" + }, + "start_col": 88, + "start_line": 41 + } + }, + "31": { + "accessible_scopes": [ + "__main__", + "__main__.fib" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 4, + "offset": 3 + }, + "reference_ids": { + "__main__.fib.first_element": 7, + "__main__.fib.n": 9, + "__main__.fib.second_element": 8 + } + }, + "hints": [], + "inst": { + "end_col": 6, + "end_line": 42, + "input_file": { + "filename": "examples/CairoZero/fibonacci.cairo" + }, + "start_col": 12, + "start_line": 40 + } + }, + "33": { + "accessible_scopes": [ + "__main__", + "__main__.fib" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 5, + "offset": 0 + }, + "reference_ids": { + "__main__.fib.first_element": 7, + "__main__.fib.n": 9, + "__main__.fib.second_element": 8 + } + }, + "hints": [], + "inst": { + "end_col": 7, + "end_line": 42, + "input_file": { + "filename": "examples/CairoZero/fibonacci.cairo" + }, + "start_col": 5, + "start_line": 40 + } + } + } + }, + "hints": { + "8": [ + { + "accessible_scopes": [ + "__main__", + "__main__.main" + ], + "code": "ids.fibonacci_claim_index = program_input['fibonacci_claim_index']", + "flow_tracking_data": { + "ap_tracking": { + "group": 2, + "offset": 1 + }, + "reference_ids": { + "__main__.main.bitwise_ptr": 3, + "__main__.main.fibonacci_claim_index": 4, + "__main__.main.output_ptr": 0, + "__main__.main.pedersen_ptr": 1, + "__main__.main.range_check_ptr": 2 + } + } + } + ] + }, + "identifiers": { + "__main__.__end__": { + "pc": 4, + "type": "label" + }, + "__main__.__start__": { + "pc": 0, + "type": "label" + }, + "__main__.fib": { + "decorators": [], + "pc": 23, + "type": "function" + }, + "__main__.fib.Args": { + "full_name": "__main__.fib.Args", + "members": { + "first_element": { + "cairo_type": "felt", + "offset": 0 + }, + "n": { + "cairo_type": "felt", + "offset": 2 + }, + "second_element": { + "cairo_type": "felt", + "offset": 1 + } + }, + "size": 3, + "type": "struct" + }, + "__main__.fib.ImplicitArgs": { + "full_name": "__main__.fib.ImplicitArgs", + "members": {}, + "size": 0, + "type": "struct" + }, + "__main__.fib.Return": { + "cairo_type": "felt", + "type": "type_definition" + }, + "__main__.fib.SIZEOF_LOCALS": { + "type": "const", + "value": 0 + }, + "__main__.fib.first_element": { + "cairo_type": "felt", + "full_name": "__main__.fib.first_element", + "references": [ + { + "ap_tracking_data": { + "group": 4, + "offset": 0 + }, + "pc": 23, + "value": "[cast(fp + (-5), felt*)]" + } + ], + "type": "reference" + }, + "__main__.fib.n": { + "cairo_type": "felt", + "full_name": "__main__.fib.n", + "references": [ + { + "ap_tracking_data": { + "group": 4, + "offset": 0 + }, + "pc": 23, + "value": "[cast(fp + (-3), felt*)]" + } + ], + "type": "reference" + }, + "__main__.fib.second_element": { + "cairo_type": "felt", + "full_name": "__main__.fib.second_element", + "references": [ + { + "ap_tracking_data": { + "group": 4, + "offset": 0 + }, + "pc": 23, + "value": "[cast(fp + (-4), felt*)]" + } + ], + "type": "reference" + }, + "__main__.main": { + "decorators": [], + "pc": 6, + "type": "function" + }, + "__main__.main.Args": { + "full_name": "__main__.main.Args", + "members": {}, + "size": 0, + "type": "struct" + }, + "__main__.main.ImplicitArgs": { + "full_name": "__main__.main.ImplicitArgs", + "members": { + "bitwise_ptr": { + "cairo_type": "felt*", + "offset": 3 + }, + "output_ptr": { + "cairo_type": "felt*", + "offset": 0 + }, + "pedersen_ptr": { + "cairo_type": "felt*", + "offset": 1 + }, + "range_check_ptr": { + "cairo_type": "felt*", + "offset": 2 + } + }, + "size": 4, + "type": "struct" + }, + "__main__.main.Return": { + "cairo_type": "()", + "type": "type_definition" + }, + "__main__.main.SIZEOF_LOCALS": { + "type": "const", + "value": 1 + }, + "__main__.main.bitwise_ptr": { + "cairo_type": "felt*", + "full_name": "__main__.main.bitwise_ptr", + "references": [ + { + "ap_tracking_data": { + "group": 2, + "offset": 0 + }, + "pc": 6, + "value": "[cast(fp + (-3), felt**)]" + } + ], + "type": "reference" + }, + "__main__.main.fibonacci_claim_index": { + "cairo_type": "felt", + "full_name": "__main__.main.fibonacci_claim_index", + "references": [ + { + "ap_tracking_data": { + "group": 2, + "offset": 1 + }, + "pc": 8, + "value": "[cast(fp, felt*)]" + } + ], + "type": "reference" + }, + "__main__.main.output_ptr": { + "cairo_type": "felt*", + "full_name": "__main__.main.output_ptr", + "references": [ + { + "ap_tracking_data": { + "group": 2, + "offset": 0 + }, + "pc": 6, + "value": "[cast(fp + (-6), felt**)]" + }, + { + "ap_tracking_data": { + "group": 3, + "offset": 0 + }, + "pc": 17, + "value": "cast([fp + (-6)] + 2, felt*)" + } + ], + "type": "reference" + }, + "__main__.main.pedersen_ptr": { + "cairo_type": "felt*", + "full_name": "__main__.main.pedersen_ptr", + "references": [ + { + "ap_tracking_data": { + "group": 2, + "offset": 0 + }, + "pc": 6, + "value": "[cast(fp + (-5), felt**)]" + } + ], + "type": "reference" + }, + "__main__.main.range_check_ptr": { + "cairo_type": "felt*", + "full_name": "__main__.main.range_check_ptr", + "references": [ + { + "ap_tracking_data": { + "group": 2, + "offset": 0 + }, + "pc": 6, + "value": "[cast(fp + (-4), felt**)]" + } + ], + "type": "reference" + }, + "__main__.main.res": { + "cairo_type": "felt", + "full_name": "__main__.main.res", + "references": [ + { + "ap_tracking_data": { + "group": 3, + "offset": 0 + }, + "pc": 16, + "value": "[cast(ap + (-1), felt*)]" + } + ], + "type": "reference" + } + }, + "main_scope": "__main__", + "prime": "0x800000000000011000000000000000000000000000000000000000000000001", + "reference_manager": { + "references": [ + { + "ap_tracking_data": { + "group": 2, + "offset": 0 + }, + "pc": 6, + "value": "[cast(fp + (-6), felt**)]" + }, + { + "ap_tracking_data": { + "group": 2, + "offset": 0 + }, + "pc": 6, + "value": "[cast(fp + (-5), felt**)]" + }, + { + "ap_tracking_data": { + "group": 2, + "offset": 0 + }, + "pc": 6, + "value": "[cast(fp + (-4), felt**)]" + }, + { + "ap_tracking_data": { + "group": 2, + "offset": 0 + }, + "pc": 6, + "value": "[cast(fp + (-3), felt**)]" + }, + { + "ap_tracking_data": { + "group": 2, + "offset": 1 + }, + "pc": 8, + "value": "[cast(fp, felt*)]" + }, + { + "ap_tracking_data": { + "group": 3, + "offset": 0 + }, + "pc": 16, + "value": "[cast(ap + (-1), felt*)]" + }, + { + "ap_tracking_data": { + "group": 3, + "offset": 0 + }, + "pc": 17, + "value": "cast([fp + (-6)] + 2, felt*)" + }, + { + "ap_tracking_data": { + "group": 4, + "offset": 0 + }, + "pc": 23, + "value": "[cast(fp + (-5), felt*)]" + }, + { + "ap_tracking_data": { + "group": 4, + "offset": 0 + }, + "pc": 23, + "value": "[cast(fp + (-4), felt*)]" + }, + { + "ap_tracking_data": { + "group": 4, + "offset": 0 + }, + "pc": 23, + "value": "[cast(fp + (-3), felt*)]" + } + ] + } +} \ No newline at end of file diff --git a/examples/CairoZero/input.json b/examples/cairo0/input.json similarity index 100% rename from examples/CairoZero/input.json rename to examples/cairo0/input.json diff --git a/prover-sdk/Cargo.toml b/prover-sdk/Cargo.toml index 1c44cbc..9bc39e5 100644 --- a/prover-sdk/Cargo.toml +++ b/prover-sdk/Cargo.toml @@ -3,26 +3,19 @@ name = "prover-sdk" version = "0.1.0" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] -common.workspace = true - +reqwest.workspace = true +url.workspace = true thiserror.workspace = true -tokio.workspace = true +common.workspace = true tracing.workspace = true -serde.workspace = true -serde_json.workspace = true -serde_with.workspace = true -bytes.workspace = true -hyper-util.workspace = true -http.workspace = true +ed25519-dalek.workspace = true prefix-hex.workspace = true -reqwest.workspace = true rand.workspace = true -ed25519-dalek.workspace = true +serde.workspace = true +serde_json.workspace = true reqwest_cookie_store.workspace = true -url.workspace = true - -[dev-dependencies] -prover.workspace = true +base64.workspace = true +starknet-types-core.workspace = true +tokio.workspace = true +futures.workspace = true \ No newline at end of file diff --git a/prover-sdk/README.md b/prover-sdk/README.md new file mode 100644 index 0000000..1a568e8 --- /dev/null +++ b/prover-sdk/README.md @@ -0,0 +1,105 @@ +# Prover SDK + +The Prover SDK is a Rust library for interacting with the Prover service. It provides functionality for authentication, proving, and error handling. + +## Generating access keys + +Before using the prover key has to be authorized by the prover operator. To generate the key use: + +```bash +cargo run --bin keygen +``` + +It will output 2 keys. + +- send the public key to the prover operator +- pass the private key to the sdk to use it. + +## Using in code + +First parse a private key corresponding to an authorized public key. + +```rust +ProverAccessKey::from_hex_string( + "0xf91350db1ca372b54376b519be8bf73a7bbbbefc4ffe169797bc3f5ea2dec740", +) +.unwrap() +``` + +Then construct an instance with + +```rust +let prover_url = Url::parse("http://localhost:3000").unwrap(); +let sdk = ProverSDK::new(key, prover_url).await?; +``` + +Then you can use below to prove an execution + +```rust +data = CairoProverInput{ + program, //CairoCompiledProgram, + program_input, //Vec, + layout, //String, +} +let proof = sdk.prove_cairo1(data).await; +``` +## Examples + +To use the SDK, follow these steps: + +Authenticate with the Prover service using your private key and the authentication URL: + +```rust +#[tokio::main] +async fn main() -> Result<(), ProverSdkErrors> { + let private_key_hex : String= env::var("PRIVATE_KEY")?; + let url_auth = "http://localhost:3000/auth"; + let url_prover = "http://localhost:3000/prove/cairo1"; + + let result = ProverSDK::new(url_auth, url_prover) + .auth(&private_key_hex) + .await?; + + // Handle authentication result + Ok(()) +} +``` + +Use the SDK to prove data: + +```rust +#[tokio::main] +async fn main() -> Result<(), SdkErrors> { + // Authentication code goes here... + + let sdk = result.build()?; + let data = read_json_file("resources/input.json").await?; + let job_id = sdk.prove(data).await?; //return job id in json format + // Handle job id + Ok(()) +} +``` + +Handle errors using the provided error types: + +```rust +#[tokio::main] +async fn main() -> Result<(), SdkErrors> { + // Authentication code goes here... + + let result = ProverSDK::new(url_auth, url_prover) + .auth(&private_key_hex) + .await; + + match result { + Ok(sdk) => { + // Continue with SDK usage... + } + Err(err) => { + // Handle authentication error + println!("Authentication failed: {}", err); + } + } + + Ok(()) +} \ No newline at end of file diff --git a/prover-sdk/src/access_key.rs b/prover-sdk/src/access_key.rs index c4ca8b8..7d14f8d 100644 --- a/prover-sdk/src/access_key.rs +++ b/prover-sdk/src/access_key.rs @@ -1,33 +1,31 @@ -use common::bytes_to_hex_string; use ed25519_dalek::SigningKey; -use prefix_hex::Error; -use serde::{Deserialize, Serialize}; -#[derive(Debug, Clone, PartialEq, Eq)] +use crate::errors::SdkErrors; + +#[derive(Debug, Clone)] pub struct ProverAccessKey(pub SigningKey); impl ProverAccessKey { pub fn new(private_key: SigningKey) -> Self { - ProverAccessKey(private_key) + Self(private_key) } - pub fn from_hex_string(hex_string: &str) -> Result { - let bytes = prefix_hex::decode::>(&hex_string)?; + pub fn from_hex_string(hex_string: &str) -> Result { + let bytes = prefix_hex::decode::>(&hex_string).map_err(|e| { + SdkErrors::PrefixError(format!("Failed to decode string to bytes {}", e)) + })?; let mut array = [0u8; 32]; array.copy_from_slice(&bytes); let signer = SigningKey::from_bytes(&array); - Ok(ProverAccessKey(signer)) + Ok(Self(signer)) } - pub fn verifying_key_as_hex_string(&self) -> String { - bytes_to_hex_string(&self.0.verifying_key().to_bytes()) + prefix_hex::encode(self.0.verifying_key().to_bytes()) } pub fn signing_key_as_hex_string(&self) -> String { - bytes_to_hex_string(&self.0.to_bytes()) + prefix_hex::encode(self.0.to_bytes()) } - - /// Notice that this key has to be register by the prover operator first. pub fn generate() -> Self { let mut rng = rand::thread_rng(); let private_key = SigningKey::generate(&mut rng); @@ -35,21 +33,61 @@ impl ProverAccessKey { } } -impl Serialize for ProverAccessKey { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - serializer.serialize_str(&bytes_to_hex_string(&self.0.to_bytes())) +#[cfg(test)] +mod tests { + use rand::{thread_rng, Rng}; + + use super::*; + fn generate_random_hex_string(length: usize) -> String { + let mut rng = thread_rng(); + let chars: Vec = (0..length) + .map(|_| { + let idx = rng.gen_range(0..16); + "0123456789abcdef".chars().nth(idx).unwrap() + }) + .collect(); + chars.into_iter().collect() } -} + #[test] + fn test_prover_access_key_with_random_inputs() { + for _ in 0..1000 { + // Generate a random hex string of different lengths + let length = thread_rng().gen_range(0..64); // Random length up to 64 characters + let hex_string = generate_random_hex_string(length); + + // Test from_hex_string with random input + if let Ok(prover_access_key) = ProverAccessKey::from_hex_string(&hex_string) { + // If we successfully created a ProverAccessKey, check the conversion methods + let signing_key_hex = prover_access_key.signing_key_as_hex_string(); + + // Recreate the ProverAccessKey from the signing key hex + if let Ok(recreated_key) = ProverAccessKey::from_hex_string(&signing_key_hex) { + assert_eq!( + prover_access_key.signing_key_as_hex_string(), + recreated_key.signing_key_as_hex_string() + ); + assert_eq!( + prover_access_key.verifying_key_as_hex_string(), + recreated_key.verifying_key_as_hex_string() + ); + } + } + + // Generate a new key and test hex string conversion + let generated_key = ProverAccessKey::generate(); + let signing_key_hex = generated_key.signing_key_as_hex_string(); -impl<'de> Deserialize<'de> for ProverAccessKey { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - let hex_string = String::deserialize(deserializer)?; - Self::from_hex_string(&hex_string).map_err(serde::de::Error::custom) + // Recreate the ProverAccessKey from the signing key hex + if let Ok(recreated_key) = ProverAccessKey::from_hex_string(&signing_key_hex) { + assert_eq!( + generated_key.signing_key_as_hex_string(), + recreated_key.signing_key_as_hex_string() + ); + assert_eq!( + generated_key.verifying_key_as_hex_string(), + recreated_key.verifying_key_as_hex_string() + ); + } + } } } diff --git a/prover-sdk/src/errors.rs b/prover-sdk/src/errors.rs index 37e8201..f8b2e82 100644 --- a/prover-sdk/src/errors.rs +++ b/prover-sdk/src/errors.rs @@ -1,57 +1,33 @@ -use reqwest::Error as ReqwestError; -use std::env::VarError; use thiserror::Error; #[derive(Debug, Error)] -pub enum ProverSdkErrors { - #[error("HTTP request failed: {0}")] - RequestFailed(#[from] ReqwestError), - - #[error("Failed to read env variable: {0}")] - EnvVarFailed(#[from] VarError), - - #[error("JSON parsing failed: {0}")] - JsonParsingFailed(String), - - #[error("Validate signature failed: {0}")] - ValidateSignatureResponseError(String), - - #[error("Prove request failed: {0}")] - ProveRequestFailed(String), - - #[error("Prove request failed: {0}")] +pub enum SdkErrors { + #[error(transparent)] + ReqwestError(#[from] reqwest::Error), + #[error(transparent)] + UrlParseError(#[from] url::ParseError), + #[error("Prover response error: {0}")] ProveResponseError(String), - - #[error("JSON parsing failed: {0}")] - ReqwestBuildError(String), - - #[error("Failed to serialize")] - SerdeError(#[from] serde_json::Error), - - #[error("Nonce not found in the response")] + #[error("Get Job response error: {0}")] + GetJobResponseError(String), + #[error("Prefix error: {0}")] + PrefixError(String), + #[error("Nonce Request error: {0}")] + NonceRequestFailed(String), + #[error(transparent)] + Parse(#[from] serde_json::Error), + #[error("Nonce not found")] NonceNotFound, - - #[error("JWT token not found in the response")] - JwtTokenNotFound, - - #[error("Reading input file failed")] - ReadFileError(#[from] std::io::Error), - - #[error("Expiration date not found")] - ExpirationNotFound, - - #[error("Signing key not found, possibly build without auth.")] + #[error("Validate Signature response error: {0}")] + ValidateSignatureResponseError(String), + #[error("JWT Token not found")] + JWTTokenNotFound, + #[error("JWT Expiration not found")] + JWTExpirationNotFound, + #[error("Signing key not found")] SigningKeyNotFound, - - #[error("Nonce request failed: {0}")] - NonceRequestFailed(String), - - #[error("Validate signature request failed: {0}")] - ValidateSignatureRequestFailed(String), - - #[error("Failed to decode hex")] - FromHexError(String), - - #[error("Failed to parse URL")] - UrlParseError(#[from] url::ParseError), + #[error("Register response error: {0}")] + RegisterResponseError(String), + #[error("SSE error: {0}")] + SSEError(String), } diff --git a/prover-sdk/src/lib.rs b/prover-sdk/src/lib.rs index 24731f9..4336a38 100644 --- a/prover-sdk/src/lib.rs +++ b/prover-sdk/src/lib.rs @@ -1,11 +1,4 @@ pub mod access_key; pub mod errors; -pub mod load; -pub mod prove_sdk_builder; -pub mod prover_sdk; - -pub use access_key::ProverAccessKey; -pub use common::{Cairo0ProverInput, Cairo1CompiledProgram, Cairo1ProverInput, CompiledProgram}; -pub use errors::ProverSdkErrors; -pub use load::{load_cairo0, load_cairo1}; -pub use prover_sdk::ProverSDK; +pub mod sdk; +pub mod sdk_builder; diff --git a/prover-sdk/src/load.rs b/prover-sdk/src/load.rs deleted file mode 100644 index b287d84..0000000 --- a/prover-sdk/src/load.rs +++ /dev/null @@ -1,28 +0,0 @@ -use std::{env, path::PathBuf}; - -use common::{Cairo0ProverInput, Cairo1ProverInput}; -use tokio::{fs::File, io::AsyncReadExt}; - -use crate::errors::ProverSdkErrors; - -pub async fn load_cairo0(file_path: PathBuf) -> Result { - let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); - let mut file = File::open(manifest_dir.join(file_path)).await?; - let mut json_string = String::new(); - file.read_to_string(&mut json_string).await?; - - let json_value: Cairo0ProverInput = serde_json::from_str(&json_string)?; - - Ok(json_value) -} - -pub async fn load_cairo1(file_path: PathBuf) -> Result { - let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); - let mut file = File::open(manifest_dir.join(file_path)).await?; - let mut json_string = String::new(); - file.read_to_string(&mut json_string).await?; - - let json_value: Cairo1ProverInput = serde_json::from_str(&json_string)?; - - Ok(json_value) -} diff --git a/prover-sdk/src/prove_sdk_builder.rs b/prover-sdk/src/prove_sdk_builder.rs deleted file mode 100644 index 0655ab9..0000000 --- a/prover-sdk/src/prove_sdk_builder.rs +++ /dev/null @@ -1,265 +0,0 @@ -use crate::access_key::ProverAccessKey; -use crate::errors::ProverSdkErrors; -use crate::prover_sdk::ProverSDK; - -use common::{bytes_to_hex_string, JWTResponse, ValidateSignatureRequest}; -use ed25519_dalek::{Signature, Signer, VerifyingKey}; -use reqwest::{cookie::Jar, Client, Url}; -use serde_json::Value; -use std::sync::Arc; - -/// ProverSDKBuilder is a builder for constructing a ProverSDK instance. -#[derive(Debug)] -pub struct ProverSDKBuilder { - client: Client, - auth: Url, - base_url: Url, - signing_key: Option, - jwt_token: Option, -} - -impl ProverSDKBuilder { - /// Creates a new ProverSDKBuilder instance. - /// - /// # Arguments - /// - /// * `url_auth` - The URL of the authentication service. - /// * `url_prover` - The URL of the Prover service. - /// - /// # Returns - /// - /// Returns a new instance of ProverSDKBuilder. - pub fn new(auth: Url, base_url: Url) -> Self { - ProverSDKBuilder { - client: Client::new(), - auth, - base_url, - signing_key: None, - jwt_token: None, - } - } - - /// Authenticates with the authentication service using the provided private key. - /// - /// # Arguments - /// - /// * `private_key_hex` - The hexadecimal representation of the private key. - /// - /// # Returns - /// - /// Returns a Result containing the ProverSDKBuilder instance with authentication - /// information if successful, or a ProverSdkErrors if an error occurs. - pub async fn auth(mut self, signing_key: ProverAccessKey) -> Result { - self.signing_key = Some(signing_key); - let jwt_response = self.get_jwt_token().await?; - self.jwt_token = Some(jwt_response.jwt_token); - Ok(self) - } - - /// Asynchronously retrieves a JWT token from the authentication service using the provided signing key. - /// - /// # Returns - /// - /// Returns a Result containing a JWTResponse if successful, or a ProverSdkErrors if an error occurs. - async fn get_jwt_token(&self) -> Result { - let signing_key = self - .signing_key - .as_ref() - .ok_or(ProverSdkErrors::SigningKeyNotFound)?; - - let public_key = signing_key.0.verifying_key(); - - let nonce = self.get_nonce(&public_key).await?; - - let signed_nonce = signing_key.0.sign(nonce.as_bytes()); - - self.validate_signature(public_key, signed_nonce).await - } - - /// Asynchronously retrieves a nonce from the authentication service using the provided public key. - /// - /// # Arguments - /// - /// * `public_key` - The public key used to request the nonce. dalek_ed25519 VerifyingKey - /// - /// # Returns - /// - /// Returns a Result containing a nonce string if successful, or a ProverSdkErrors if an error occurs. - async fn get_nonce(&self, public_key: &VerifyingKey) -> Result { - let url_with_params = format!( - "{}?public_key={}", - self.auth, - bytes_to_hex_string(public_key.as_bytes()) - ); - - let response = match self.client.get(&url_with_params).send().await { - Ok(response) => response, - Err(reqwest_error) => { - return Err(ProverSdkErrors::NonceRequestFailed(format!( - "Failed to send HTTP request to URL: {}. Error: {}", - url_with_params, reqwest_error - ))); - } - }; - if !response.status().is_success() { - // If the status is not successful, return an appropriate error - return Err(ProverSdkErrors::NonceRequestFailed(format!( - "Failed to get nonce from URL: {} with status code: {}", - url_with_params, - response.status(), - ))); - } - - let response_text = response.text().await.map_err(|e| { - ProverSdkErrors::NonceRequestFailed(format!( - "Failed to read response text from URL: {}. Error: {}", - url_with_params, e - )) - })?; - - let json_body: Value = serde_json::from_str(&response_text).map_err(|e| { - ProverSdkErrors::JsonParsingFailed(format!( - "Failed to parse JSON response from URL: {}. Error: {}", - url_with_params, e - )) - })?; - - let nonce = json_body["nonce"] - .as_str() - .ok_or(ProverSdkErrors::NonceNotFound)? - .to_string(); - - Ok(nonce) - } - - /// Asynchronously validates the signature of the provided nonce and retrieves a JWT token from the authentication service. - /// - /// # Arguments - /// - /// * `public_key` - The public key used to request the nonce. - /// * `nonce` - The nonce received from the authentication service. - /// * `signed_nonce` - The signature of the nonce. - /// - /// # Returns - /// - /// Returns a Result containing a JWTResponse if successful, or a ProverSdkErrors if an error occurs. - async fn validate_signature( - &self, - public_key: VerifyingKey, - signed_nonce: Signature, - ) -> Result { - let req = ValidateSignatureRequest { - public_key, - signature: signed_nonce, - }; - - let response = match self - .client - .post(self.auth.clone()) - .header(reqwest::header::CONTENT_TYPE, "application/json") - .json(&req) - .send() - .await - { - Ok(response) => response, - Err(reqwest_error) => { - return Err(ProverSdkErrors::ValidateSignatureRequestFailed(format!( - "Failed to send HTTP request to URL: {}. Error: {}", - self.auth, reqwest_error - ))); - } - }; - - if !response.status().is_success() { - return Err(ProverSdkErrors::ValidateSignatureResponseError(format!( - "Received unsuccessful status code ({}) from URL: {}", - response.status(), - self.auth - ))); - } - - let json_body: Value = match response.json().await { - Ok(json_body) => json_body, - Err(json_error) => { - return Err(ProverSdkErrors::JsonParsingFailed(format!( - "Failed to parse JSON response from URL: {}. Error: {}", - self.auth, json_error - ))); - } - }; - - let jwt_token = json_body["jwt_token"] - .as_str() - .ok_or(ProverSdkErrors::JwtTokenNotFound)? - .to_string(); - let expiration = json_body["expiration"] - .as_u64() - .ok_or(ProverSdkErrors::ExpirationNotFound)?; - - Ok(JWTResponse { - jwt_token, - expiration, - }) - } - - /// Builds the ProverSDK instance. - /// - /// # Returns - /// - /// Returns a Result containing the constructed ProverSDK instance if successful, - /// or a ProverSdkErrors if an error occurs. - pub fn build(self) -> Result { - let signing_key = self - .signing_key - .ok_or(ProverSdkErrors::SigningKeyNotFound)?; - let jwt_token = self.jwt_token.ok_or(ProverSdkErrors::JwtTokenNotFound)?; - - let prover = self - .base_url - .join("") - .map_err(ProverSdkErrors::UrlParseError)?; - let cookie_jar = Arc::new(Jar::default()); - let secure_attribute = if prover.scheme() == "https" { - "Secure; " - } else { - "" - }; - - cookie_jar.add_cookie_str( - &format!( - "jwt_token={}; HttpOnly; {} SameSite=None; Path=/", - jwt_token, secure_attribute - ), - &prover, - ); - - let client = reqwest::Client::builder() - .cookie_store(true) - .cookie_provider(cookie_jar) - .build() - .map_err(|e| { - ProverSdkErrors::ReqwestBuildError(format!("Failed to build reqwest client: {}", e)) - })?; - - Ok(ProverSDK { - client, - prover_cairo0: self - .base_url - .join("/prove/cairo0") - .map_err(ProverSdkErrors::UrlParseError)?, - prover_cairo1: self - .base_url - .join("/prove/cairo1") - .map_err(ProverSdkErrors::UrlParseError)?, - register: self - .base_url - .join("/register") - .map_err(ProverSdkErrors::UrlParseError)?, - verify: self - .base_url - .join("/verify") - .map_err(ProverSdkErrors::UrlParseError)?, - authority: signing_key, - }) - } -} diff --git a/prover-sdk/src/prover_sdk.rs b/prover-sdk/src/prover_sdk.rs deleted file mode 100644 index da693c1..0000000 --- a/prover-sdk/src/prover_sdk.rs +++ /dev/null @@ -1,173 +0,0 @@ -use crate::errors::ProverSdkErrors; -use crate::prove_sdk_builder::ProverSDKBuilder; -use crate::ProverAccessKey; - -use common::{AddAuthorizedRequest, ProverInput}; -use ed25519_dalek::{ed25519::signature::SignerMut, VerifyingKey}; -use reqwest::Client; -use url::Url; - -#[derive(Debug, Clone)] -/// ProverSDK is a struct representing a client for interacting with the Prover service. -pub struct ProverSDK { - pub client: Client, - pub prover_cairo0: Url, - pub prover_cairo1: Url, - pub register: Url, - pub authority: ProverAccessKey, - pub verify: Url, -} - -impl ProverSDK { - /// Creates a new ProverSDK instance. - /// - /// # Arguments - /// - /// * `url_auth` - The URL of the authentication service. - /// * `url_prover` - The URL of the Prover service. - /// - /// # Returns - /// - /// Returns a `ProverSDKBuilder` which can be used to further configure the ProverSDK. - pub async fn new(access_key: ProverAccessKey, url: Url) -> Result { - let auth_url = url.join("auth").map_err(ProverSdkErrors::UrlParseError)?; - let prover_url = url - .join("prove/cairo1") - .map_err(ProverSdkErrors::UrlParseError)?; - - ProverSDKBuilder::new(auth_url, prover_url) - .auth(access_key) - .await? - .build() - } - - /// Sends the provided data to the Prover service and returns the prover output. - /// - /// # Arguments - /// - /// * `data` - The data to be proved, in JSON format. - /// - /// # Returns - /// - /// Returns a `Result` containing a string representing the response from the Prover service - /// if successful, or a `ProverSdkErrors` if an error occurs. - pub async fn prove_cairo0(&self, data: T) -> Result - where - T: ProverInput + Send + 'static, - { - self.prove(data, self.prover_cairo0.clone()).await - } - - /// Sends the provided data to the Prover service and returns the prover output. - /// - /// # Arguments - /// - /// * `data` - The data to be proved, in JSON format. - /// - /// # Returns - /// - /// Returns a `Result` containing a string representing the response from the Prover service - /// if successful, or a `ProverSdkErrors` if an error occurs. - pub async fn prove_cairo1(&self, data: T) -> Result - where - T: ProverInput + Send + 'static, - { - self.prove(data, self.prover_cairo1.clone()).await - } - - async fn prove(&self, data: T, url: Url) -> Result - where - T: ProverInput + Send + 'static, - { - let response = match self - .client - .post(url.clone()) - .json(&data.serialize()) - .send() - .await - { - Ok(response) => response, - Err(request_error) => { - return Err(ProverSdkErrors::ProveRequestFailed(format!( - "Failed to send HTTP request to URL: {}. Error: {}", - url, request_error - ))); - } - }; - - if !response.status().is_success() { - return Err(ProverSdkErrors::ProveResponseError(format!( - "Received unsuccessful status code ({}) from URL: {}", - response.status(), - url - ))); - } - - let response_data = match response.text().await { - Ok(response_text) => response_text, - Err(text_error) => { - return Err(ProverSdkErrors::ProveResponseError(format!( - "Failed to read response text from URL: {}. Error: {}", - url, text_error - ))); - } - }; - - Ok(response_data) - } - - pub async fn register(&mut self, key: VerifyingKey) -> Result { - let signature = self.authority.0.sign(&key.to_bytes()); - let req = AddAuthorizedRequest { - signature, - authority: self.authority.0.verifying_key(), - new_key: key, - }; - - let response = match self - .client - .post(self.register.clone()) - .json(&req) - .send() - .await - { - Ok(response) => response, - Err(request_error) => { - return Err(ProverSdkErrors::ProveRequestFailed(format!( - "Failed to send HTTP request to URL: {}. Error: {}", - self.register, request_error - ))); - } - }; - - if !response.status().is_success() { - return Err(ProverSdkErrors::ProveResponseError(format!( - "Received unsuccessful status code ({}) from URL: {}", - response.status(), - self.register - ))); - } - - let response_data = match response.text().await { - Ok(response_text) => response_text, - Err(text_error) => { - return Err(ProverSdkErrors::ProveResponseError(format!( - "Failed to read response text from URL: {}. Error: {}", - self.register, text_error - ))); - } - }; - - Ok(response_data) - } - pub async fn verify(self, proof: String) -> Result { - let response = self - .client - .post(self.verify.clone()) - .json(&proof) - .send() - .await?; - let response_data = response.text().await?; - Ok(response_data) - } -} diff --git a/prover-sdk/src/sdk.rs b/prover-sdk/src/sdk.rs new file mode 100644 index 0000000..9219160 --- /dev/null +++ b/prover-sdk/src/sdk.rs @@ -0,0 +1,126 @@ +use crate::{access_key::ProverAccessKey, errors::SdkErrors, sdk_builder::ProverSDKBuilder}; +use common::{requests::AddKeyRequest, ProverInput}; +use ed25519_dalek::{ed25519::signature::SignerMut, VerifyingKey}; +use futures::StreamExt; +use reqwest::{Client, Response}; +use url::Url; +#[derive(Debug, Clone)] +/// ProverSDK is a struct representing a client for interacting with the Prover service. +pub struct ProverSDK { + pub client: Client, + pub prover_cairo0: Url, + pub prover_cairo: Url, + pub verify: Url, + pub get_job: Url, + pub register: Url, + pub sse: Url, + pub authority: ProverAccessKey, +} + +impl ProverSDK { + pub async fn new(url: Url, access_key: ProverAccessKey) -> Result { + let url = if !url.as_str().ends_with('/') { + let mut url_with_slash = url.clone(); + url_with_slash.set_path(&format!("{}/", url.path())); + url_with_slash + } else { + url + }; + let auth_url = url.join("auth")?; + ProverSDKBuilder::new(auth_url, url) + .auth(access_key) + .await? + .build() + } + + pub async fn prove_cairo0(&self, data: T) -> Result + where + T: ProverInput + Send + 'static, + { + self.prove(data, self.prover_cairo0.clone()).await + } + + pub async fn prove_cairo(&self, data: T) -> Result + where + T: ProverInput + Send + 'static, + { + self.prove(data, self.prover_cairo.clone()).await + } + + async fn prove(&self, data: T, url: Url) -> Result + where + T: ProverInput + Send + 'static, + { + let response = self + .client + .post(url.clone()) + .json(&data.serialize()) + .send() + .await?; + + if !response.status().is_success() { + let response_data: String = response.text().await?; + tracing::error!("{}", response_data); + return Err(SdkErrors::ProveResponseError(response_data)); + } + let response_data = response.text().await?; + + Ok(response_data) + } + pub async fn verify(self, proof: String) -> Result { + let response = self + .client + .post(self.verify.clone()) + .json(&proof) + .send() + .await?; + let response_data = response.text().await?; + Ok(response_data) + } + pub async fn get_job(&self, job_id: u64) -> Result { + let url = format!("{}/{}", self.get_job.clone().as_str(), job_id); + let response = self.client.get(url).send().await?; + + if !response.status().is_success() { + let response_data: String = response.text().await?; + tracing::error!("{}", response_data); + return Err(SdkErrors::GetJobResponseError(response_data)); + } + Ok(response) + } + pub async fn register(&mut self, key: VerifyingKey) -> Result<(), SdkErrors> { + let signature = self.authority.0.sign(key.as_bytes()); + let request = AddKeyRequest { + signature, + new_key: key, + authority: self.authority.0.verifying_key(), + }; + let response = self + .client + .post(self.register.clone()) + .json(&request) + .send() + .await?; + if !response.status().is_success() { + return Err(SdkErrors::RegisterResponseError(format!( + "Failed to register key with status code: {}", + response.status(), + ))); + } + Ok(()) + } + pub async fn sse(&self, job_id: u64) -> Result<(), SdkErrors> { + let url = format!("{}?job_id={}", self.sse.clone().as_str(), job_id); + let response = self.client.get(url).send().await?; + if !response.status().is_success() { + return Err(SdkErrors::SSEError(format!( + "Failed to get SSE with status code: {}", + response.status(), + ))); + } + + let mut stream = response.bytes_stream(); + while let Some(_item) = stream.next().await {} + Ok(()) + } +} diff --git a/prover-sdk/src/sdk_builder.rs b/prover-sdk/src/sdk_builder.rs new file mode 100644 index 0000000..428c6ed --- /dev/null +++ b/prover-sdk/src/sdk_builder.rs @@ -0,0 +1,167 @@ +use crate::{access_key::ProverAccessKey, errors::SdkErrors, sdk::ProverSDK}; +use common::{ + models::JWTResponse, + requests::{GenerateNonceRequest, Message, ValidateSignatureRequest}, +}; +use ed25519_dalek::{Signature, Signer, SigningKey, VerifyingKey}; +use reqwest::{cookie::Jar, Client}; +use serde_json::Value; +use std::sync::Arc; +use url::Url; + +#[derive(Debug)] +pub struct ProverSDKBuilder { + client: Client, + base_url: Url, + auth: Url, + signing_key: Option, + session_key: Option, + jwt_token: Option, +} +impl ProverSDKBuilder { + pub fn new(auth: Url, base_url: Url) -> Self { + ProverSDKBuilder { + client: Client::new(), + auth, + base_url, + signing_key: None, + session_key: None, + jwt_token: None, + } + } + pub async fn get_nonce(&self, public_key: &VerifyingKey) -> Result { + let nonce_req = GenerateNonceRequest { + public_key: serde_json::to_string(&public_key)?, + }; + let response = self + .client + .get(self.auth.clone()) + .query(&nonce_req) + .send() + .await?; + + if !response.status().is_success() { + return Err(SdkErrors::NonceRequestFailed(format!( + "Failed to get nonce from URL: {} with status code: {}", + self.auth, + response.status(), + ))); + } + + let response_text = response.text().await?; + + let json_body: Value = serde_json::from_str(&response_text)?; + + let nonce = json_body["nonce"] + .as_str() + .ok_or(SdkErrors::NonceNotFound)? + .to_string(); + + Ok(nonce) + } + pub async fn validate_signature( + &self, + signed_message: Signature, + message: Message, + ) -> Result { + let request = ValidateSignatureRequest { + signature: signed_message, + message, + }; + let response = self + .client + .post(self.auth.clone()) + .header(reqwest::header::CONTENT_TYPE, "application/json") + .json(&request) + .send() + .await?; + if !response.status().is_success() { + return Err(SdkErrors::ValidateSignatureResponseError(format!( + "Failed to validate signature with status code: {}", + response.status(), + ))); + } + let json_body: Value = response.json().await?; + let jwt_token = json_body["jwt_token"] + .as_str() + .ok_or(SdkErrors::JWTTokenNotFound)? + .to_string(); + let expiration = json_body["expiration"] + .as_u64() + .ok_or(SdkErrors::JWTExpirationNotFound)?; + Ok(JWTResponse { + jwt_token, + expiration, + session_key: self.session_key.as_ref().map(|k| k.verifying_key()), + }) + } + + pub async fn auth(mut self, signing_key: ProverAccessKey) -> Result { + self.signing_key = Some(signing_key); + let jwt_response = self.get_jwt_token().await?; + self.jwt_token = Some(jwt_response.jwt_token); + Ok(self) + } + + async fn get_jwt_token(&mut self) -> Result { + let signing_key = self + .signing_key + .as_ref() + .ok_or(SdkErrors::SigningKeyNotFound)?; + + let public_key = signing_key.0.verifying_key(); + + let nonce = self.get_nonce(&public_key).await?; + self.session_key = Some(ProverAccessKey::generate().0); + let session_public_key = self + .session_key + .as_ref() + .ok_or(SdkErrors::SigningKeyNotFound)? + .verifying_key(); + let message = Message { + session_key: session_public_key, + nonce, + }; + let message_string = serde_json::to_string(&message)?; + let signed_message = signing_key.0.sign(message_string.as_bytes()); + self.validate_signature(signed_message, message).await + } + + pub fn build(self) -> Result { + let signing_key = self.signing_key.ok_or(SdkErrors::SigningKeyNotFound)?; + + let jwt_token = self.jwt_token.ok_or(SdkErrors::JWTTokenNotFound)?; + + let prover = self.base_url.join("")?; + + let cookie_jar = Arc::new(Jar::default()); + let secure_attribute = if prover.scheme() == "https" { + "Secure; " + } else { + "" + }; + + cookie_jar.add_cookie_str( + &format!( + "jwt_token={}; HttpOnly; {} SameSite=None; Path=/", + jwt_token, secure_attribute + ), + &prover, + ); + let client = reqwest::Client::builder() + .cookie_store(true) + .cookie_provider(cookie_jar) + .build()?; + + Ok(ProverSDK { + client, + prover_cairo0: self.base_url.join("/prove/cairo0")?, + prover_cairo: self.base_url.join("/prove/cairo")?, + verify: self.base_url.join("/verify")?, + get_job: self.base_url.join("/get-job")?, + register: self.base_url.join("/register")?, + sse: self.base_url.join("/sse")?, + authority: signing_key, + }) + } +} diff --git a/prover-sdk/tests/auth_test.rs b/prover-sdk/tests/auth_test.rs new file mode 100644 index 0000000..14eb06c --- /dev/null +++ b/prover-sdk/tests/auth_test.rs @@ -0,0 +1,22 @@ +#[cfg(test)] +mod tests { + use prover_sdk::{access_key::ProverAccessKey, sdk::ProverSDK}; + use url::Url; + + #[tokio::test] + async fn test_authorized_access() { + let private_key = std::env::var("PRIVATE_KEY").unwrap(); + let url = std::env::var("PROVER_URL").unwrap(); + let access_key = ProverAccessKey::from_hex_string(&private_key).unwrap(); + let url = Url::parse(&url).unwrap(); + let _sdk = ProverSDK::new(url, access_key).await.unwrap(); + } + #[tokio::test] + async fn test_unauthorized_access() { + let unauthorized_key = ProverAccessKey::generate(); + let url = std::env::var("PROVER_URL").unwrap(); + let url = Url::parse(&url).unwrap(); + let sdk = ProverSDK::new(url, unauthorized_key).await; + assert!(sdk.is_err()); + } +} diff --git a/prover-sdk/tests/helpers/mod.rs b/prover-sdk/tests/helpers/mod.rs new file mode 100644 index 0000000..1739c5d --- /dev/null +++ b/prover-sdk/tests/helpers/mod.rs @@ -0,0 +1,21 @@ +use prover_sdk::sdk::ProverSDK; +use serde::Deserialize; +use serde_json::Value; + +#[derive(Deserialize)] +pub struct JobId { + pub job_id: u64, +} +pub async fn fetch_job(sdk: ProverSDK, job: String) -> String { + let job: JobId = serde_json::from_str(&job).unwrap(); + println!("Job ID: {}", job.job_id); + sdk.sse(job.job_id).await.unwrap(); + let response = sdk.get_job(job.job_id).await.unwrap(); + let response = response.text().await.unwrap(); + let json_response: Value = serde_json::from_str(&response).unwrap(); + return json_response + .get("result") + .and_then(Value::as_str) + .unwrap_or("No result found") + .to_string(); +} diff --git a/prover-sdk/tests/prove_test.rs b/prover-sdk/tests/prove_test.rs new file mode 100644 index 0000000..82e67ef --- /dev/null +++ b/prover-sdk/tests/prove_test.rs @@ -0,0 +1,99 @@ +use common::{ + cairo0_prover_input::{Cairo0CompiledProgram, Cairo0ProverInput}, + cairo_prover_input::{CairoCompiledProgram, CairoProverInput}, +}; +use helpers::fetch_job; +use prover_sdk::{access_key::ProverAccessKey, sdk::ProverSDK}; +use serde_json::Value; +use starknet_types_core::felt::Felt; +use url::Url; +mod helpers; + +#[tokio::test] +async fn test_cairo_prove() { + let private_key = std::env::var("PRIVATE_KEY").unwrap(); + let url = std::env::var("PROVER_URL").unwrap(); + let access_key = ProverAccessKey::from_hex_string(&private_key).unwrap(); + let url = Url::parse(&url).unwrap(); + let sdk = ProverSDK::new(url, access_key).await.unwrap(); + let program = std::fs::read_to_string("../examples/cairo/fibonacci_compiled.json").unwrap(); + let program: CairoCompiledProgram = serde_json::from_str(&program).unwrap(); + let program_input_string = std::fs::read_to_string("../examples/cairo/input.json").unwrap(); + let mut program_input: Vec = Vec::new(); + for part in program_input_string.split(',') { + let felt = Felt::from_dec_str(part).unwrap(); + program_input.push(felt); + } + let layout = "recursive".to_string(); + let data = CairoProverInput { + program, + layout, + program_input, + }; + let job = sdk.prove_cairo(data).await.unwrap(); + let result = fetch_job(sdk.clone(), job).await; + let job = sdk.clone().verify(result).await.unwrap(); + let result = fetch_job(sdk.clone(), job).await; + assert_eq!("true", result); +} + +#[tokio::test] +async fn test_cairo0_prove() { + let private_key = std::env::var("PRIVATE_KEY").unwrap(); + let url = std::env::var("PROVER_URL").unwrap(); + let access_key = ProverAccessKey::from_hex_string(&private_key).unwrap(); + let url = Url::parse(&url).unwrap(); + let sdk = ProverSDK::new(url, access_key).await.unwrap(); + let program = std::fs::read_to_string("../examples/cairo0/fibonacci_compiled.json").unwrap(); + let program: Cairo0CompiledProgram = serde_json::from_str(&program).unwrap(); + let program_input_string = std::fs::read_to_string("../examples/cairo0/input.json").unwrap(); + let program_input: Value = serde_json::from_str(&program_input_string).unwrap(); + let layout = "recursive".to_string(); + let data = Cairo0ProverInput { + program, + layout, + program_input, + }; + let job = sdk.prove_cairo0(data).await.unwrap(); + let result = fetch_job(sdk.clone(), job).await; + let job = sdk.clone().verify(result).await.unwrap(); + let result = fetch_job(sdk.clone(), job).await; + assert_eq!("true", result); +} +#[tokio::test] +async fn test_cairo_multi_prove() { + let private_key = std::env::var("PRIVATE_KEY").unwrap(); + let url = std::env::var("PROVER_URL").unwrap(); + let access_key = ProverAccessKey::from_hex_string(&private_key).unwrap(); + let url = Url::parse(&url).unwrap(); + let sdk = ProverSDK::new(url, access_key).await.unwrap(); + let program = std::fs::read_to_string("../examples/cairo/fibonacci_compiled.json").unwrap(); + let program: CairoCompiledProgram = serde_json::from_str(&program).unwrap(); + let program_input_string = std::fs::read_to_string("../examples/cairo/input.json").unwrap(); + let mut program_input: Vec = Vec::new(); + for part in program_input_string.split(',') { + let felt = Felt::from_dec_str(part).unwrap(); + program_input.push(felt); + } + let layout = "recursive".to_string(); + let data = CairoProverInput { + program, + layout, + program_input, + }; + let job1 = sdk.prove_cairo(data.clone()).await.unwrap(); + let job2 = sdk.prove_cairo(data.clone()).await.unwrap(); + let job3 = sdk.prove_cairo(data.clone()).await.unwrap(); + let result = fetch_job(sdk.clone(), job1).await; + let job = sdk.clone().verify(result).await.unwrap(); + let result = fetch_job(sdk.clone(), job).await; + assert_eq!("true", result); + let result = fetch_job(sdk.clone(), job2).await; + let job = sdk.clone().verify(result).await.unwrap(); + let result = fetch_job(sdk.clone(), job).await; + assert_eq!("true", result); + let result = fetch_job(sdk.clone(), job3).await; + let job = sdk.clone().verify(result).await.unwrap(); + let result = fetch_job(sdk.clone(), job).await; + assert_eq!("true", result); +} diff --git a/prover-sdk/tests/register_test.rs b/prover-sdk/tests/register_test.rs new file mode 100644 index 0000000..873078e --- /dev/null +++ b/prover-sdk/tests/register_test.rs @@ -0,0 +1,30 @@ +use prover_sdk::{access_key::ProverAccessKey, sdk::ProverSDK}; +use url::Url; + +#[tokio::test] +async fn test_register_authorized() { + let url = std::env::var("PROVER_URL").unwrap(); + let admin_key = std::env::var("ADMIN_PRIVATE_KEY").unwrap(); + let admin_key = ProverAccessKey::from_hex_string(&admin_key).unwrap(); + let random_key = ProverAccessKey::generate(); + let url = Url::parse(&url).unwrap(); + let mut sdk = ProverSDK::new(url.clone(), admin_key).await.unwrap(); + sdk.register(random_key.0.verifying_key()).await.unwrap(); + let new_sdk = ProverSDK::new(url, random_key).await; + assert!(new_sdk.is_ok()); +} +#[tokio::test] +async fn test_register_unauthorized() { + let url = std::env::var("PROVER_URL").unwrap(); + let authorized_key = std::env::var("PRIVATE_KEY").unwrap(); + let authorized_key = ProverAccessKey::from_hex_string(&authorized_key).unwrap(); + let url = Url::parse(&url).unwrap(); + //Connecting with sdk using authorized key, but not recognized as admin key + let mut sdk = ProverSDK::new(url.clone(), authorized_key).await.unwrap(); + let random_key = ProverAccessKey::generate(); + //Trying to register a new key using not admin key, should return error + let response = sdk.register(random_key.0.verifying_key()).await; + assert!(response.is_err()); + let new_sdk = ProverSDK::new(url, random_key).await; + assert!(new_sdk.is_err()); +} diff --git a/prover-sdk/tests/sdk_test.rs b/prover-sdk/tests/sdk_test.rs deleted file mode 100644 index f2eb0db..0000000 --- a/prover-sdk/tests/sdk_test.rs +++ /dev/null @@ -1,130 +0,0 @@ -pub use access_key::ProverAccessKey; -pub use common::{Cairo0ProverInput, Cairo1CompiledProgram, Cairo1ProverInput, CompiledProgram}; -pub use errors::ProverSdkErrors; -pub use load::{load_cairo0, load_cairo1}; -pub use prover_sdk::ProverSDK; -use prover_sdk::{access_key, errors, load}; - -#[cfg(test)] -mod tests { - use std::path::PathBuf; - - use crate::load::{load_cairo0, load_cairo1}; - use crate::ProverAccessKey; - use prover_sdk::{ProverSDK, ProverSdkErrors}; - use url::Url; - - fn get_signing_key() -> ProverAccessKey { - ProverAccessKey::from_hex_string( - "0x5883b0e30b008e48af3d0bf5cfc138fb6093496da6f87d24b65def88470356d3", - // Corresponding to 0xd16b71c90dbf897e5964d2f267d04664b3c035036559d712994739ea6cf2fd9f public key. - ) - .unwrap() - } - #[tokio::test] - async fn test_prover_cairo0() -> Result<(), ProverSdkErrors> { - let prover_url = Url::parse("http://localhost:3040").unwrap(); // Provide an invalid URL - let sdk = ProverSDK::new(get_signing_key(), prover_url).await?; - - let data = load_cairo0(PathBuf::from("../examples/CairoZero/prover_input.json")).await?; - let proof = sdk.prove_cairo0(data).await; - // If authentication fails, print out the error message - assert!(proof.is_ok(), "Failed to prove with invalid url"); - // If authentication fails, print out the error message for debugging purposes - if let Err(err) = proof { - println!(" error: {}", err); - } else { - let result: Result = sdk.verify(proof.unwrap()).await; - assert!(result.is_ok(), "Failed to verify proof"); - assert_eq!(result.unwrap(), "true"); - } - Ok(()) - } - - #[tokio::test] - async fn test_verify_invalid_proof() { - let prover_url = Url::parse("http://localhost:3040").unwrap(); // Provide an invalid URL - let sdk = ProverSDK::new(get_signing_key(), prover_url).await.unwrap(); - let result = sdk.verify("invalid_proof".to_string()).await; - assert!(result.is_ok(), "Failed to verify proof"); - assert_eq!(result.unwrap(), "false"); - } - #[tokio::test] - async fn test_prover_cairo1() -> Result<(), ProverSdkErrors> { - let prover_url = Url::parse("http://localhost:3040").unwrap(); - - // Act: Attempt to authenticate with the valid private key and invalid URL for authentication - let sdk = ProverSDK::new(get_signing_key(), prover_url).await?; - - let data = load_cairo1(PathBuf::from( - "../examples/Cairo/fibonacci_prover_input.json", - )) - .await?; - let proof = sdk.prove_cairo1(data).await; - // If authentication fails, print out the error message - assert!(proof.is_ok(), "Failed to prove with invalid url"); - - // If authentication fails, print out the error message for debugging purposes - if let Err(err) = proof { - println!(" error: {}", err); - } else { - let result: Result = sdk.verify(proof.unwrap()).await; - assert!(result.is_ok(), "Failed to verify proof"); - assert_eq!(result.unwrap(), "true"); - } - Ok(()) - } - - #[tokio::test] - async fn test_invalid_url_auth() -> Result<(), ProverSdkErrors> { - // Arrange: Set up any necessary data or dependencies - let prover_url = Url::parse("http://wrong:1234").unwrap(); // Provide an invalid URL for authentication - - // Act: Attempt to authenticate with the valid private key and invalid URL for authentication - let result = ProverSDK::new(get_signing_key(), prover_url).await; - // Assert: Check that authentication fails due to invalid URL - assert!( - result.is_err(), - "Expected authentication to fail with invalid URL for authentication" - ); - // If authentication fails, print out the error message - if let Err(err) = result { - println!("Error message: {}", err); - } - Ok(()) - } - - #[tokio::test] - async fn test_invalid_prover() -> Result<(), ProverSdkErrors> { - // Arrange: Set up any necessary data or dependencies - let prover_url: Url = Url::parse("http://localhost:3040").unwrap(); - - // Act: Attempt to authenticate with the valid private key and valid URL for authentication - let sdk = ProverSDK::new(get_signing_key(), prover_url).await?; - //Act: Load wrong prover input to test invalid prover version - - let data = load_cairo1(PathBuf::from( - "../examples/Cairo/fibonacci_prover_input.json", - )) - .await?; - - let proof = sdk.prove_cairo0(data).await; - // If authentication fails, print out the error message - assert!(proof.is_err(), "Failed to prove with invalid url"); - Ok(()) - } - - #[tokio::test] - async fn test_register() -> Result<(), ProverSdkErrors> { - let prover_url: Url = Url::parse("http://localhost:3040").unwrap(); - let new_key = ProverAccessKey::generate(); - - // Act: Attempt to authenticate with the valid private key - let mut sdk = ProverSDK::new(get_signing_key(), prover_url).await?; - sdk.register(new_key.0.verifying_key()).await?; - - // If authentication fails, print out the error message - - Ok(()) - } -} diff --git a/prover-sdk/tests/verify_test.rs b/prover-sdk/tests/verify_test.rs new file mode 100644 index 0000000..2b28eb9 --- /dev/null +++ b/prover-sdk/tests/verify_test.rs @@ -0,0 +1,51 @@ +use common::cairo_prover_input::{CairoCompiledProgram, CairoProverInput}; +use helpers::fetch_job; +use prover_sdk::{access_key::ProverAccessKey, sdk::ProverSDK}; +use starknet_types_core::felt::Felt; +use url::Url; + +mod helpers; + +#[tokio::test] +async fn test_verify_invalid_proof() { + let private_key = std::env::var("PRIVATE_KEY").unwrap(); + let url = std::env::var("PROVER_URL").unwrap(); + let access_key = ProverAccessKey::from_hex_string(&private_key).unwrap(); + let url = Url::parse(&url).unwrap(); + let sdk = ProverSDK::new(url, access_key).await.unwrap(); + let job = sdk + .clone() + .verify("invalid_proof".to_string()) + .await + .unwrap(); + let result = fetch_job(sdk.clone(), job).await; + assert_eq!("false", result); +} + +#[tokio::test] +async fn test_verify_valid_proof() { + let private_key = std::env::var("PRIVATE_KEY").unwrap(); + let url = std::env::var("PROVER_URL").unwrap(); + let access_key = ProverAccessKey::from_hex_string(&private_key).unwrap(); + let url = Url::parse(&url).unwrap(); + let sdk = ProverSDK::new(url, access_key).await.unwrap(); + let program = std::fs::read_to_string("../examples/cairo/fibonacci_compiled.json").unwrap(); + let program: CairoCompiledProgram = serde_json::from_str(&program).unwrap(); + let program_input_string = std::fs::read_to_string("../examples/cairo/input.json").unwrap(); + let mut program_input: Vec = Vec::new(); + for part in program_input_string.split(',') { + let felt = Felt::from_dec_str(part).unwrap(); + program_input.push(felt); + } + let layout = "recursive".to_string(); + let data = CairoProverInput { + program, + layout, + program_input, + }; + let job = sdk.clone().prove_cairo(data).await.unwrap(); + let result = fetch_job(sdk.clone(), job).await; + let job = sdk.clone().verify(result).await.unwrap(); + let result = fetch_job(sdk.clone(), job).await; + assert_eq!("true", result); +} diff --git a/prover/Cargo.toml b/prover/Cargo.toml index 951cf7f..1b609ed 100644 --- a/prover/Cargo.toml +++ b/prover/Cargo.toml @@ -3,27 +3,27 @@ name = "prover" version.workspace = true edition.workspace = true -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] axum.workspace = true -bytes.workspace = true -chrono.workspace = true clap.workspace = true +tracing.workspace = true +tracing-subscriber.workspace = true +tokio.workspace = true +serde_json.workspace = true +thiserror.workspace = true +tempfile.workspace = true +serde.workspace = true common.workspace = true -curve25519-dalek.workspace = true -ed25519-dalek.workspace = true jsonwebtoken.workspace = true -lazy_static.workspace = true +axum-extra.workspace = true +once_cell.workspace = true +serde_with.workspace = true +bytes.workspace = true prefix-hex.workspace = true rand.workspace = true -serde_json.workspace = true -serde_with.workspace = true -serde.workspace = true -thiserror.workspace = true -tokio.workspace = true -tower-http.workspace = true -tracing-subscriber.workspace = true -tracing.workspace = true -utils.workspace = true -config-generator.workspace = true +ed25519-dalek.workspace = true +chrono.workspace = true +base64.workspace = true +starknet-types-core.workspace = true +futures.workspace = true +async-stream.workspace = true \ No newline at end of file diff --git a/prover/README.md b/prover/README.md new file mode 100644 index 0000000..4a7f262 --- /dev/null +++ b/prover/README.md @@ -0,0 +1,134 @@ + +# Cairo Proving Server + +The Cairo Proving Server is the core component responsible for managing and verifying proofs within the Cairo proving system. It handles incoming proof requests, manages authorization, and coordinates the proving tasks. + +## Example Usage + +Here is an example of running the server with custom settings: + +```sh +cairo-prover-server --host 127.0.0.1 --port 8080 --message-expiration-time 7200 --session-expiration-time 14400 --jwt-secret-key "my_super_secret_key" --authorized-keys-path /path/to/authorized_keys.json --authorized-keys "key1,key2,key3" --num-workes 8 --admin-key "admin_super_secret_key" +``` +## Command-Line Options + +The server can be configured via command-line arguments or environment variables. The following options are available: + +### 1. `--host` + +- **Environment Variable:** `HOST` +- **Default:** `0.0.0.0` +- **Example:** + + ```sh + --host 127.0.0.1 + ``` + + +### 2. `--port`, `-p` + +- **Environment Variable:** `PORT` +- **Default:** `3000` +- **Example:** + + ```sh + --port 8080 + ``` + + +### 3. `--message-expiration-time`, `-m` + +- **Environment Variable:** `MESSAGE_EXPIRATION_TIME` +- **Default:** `3600` +- **Example:** + + ```sh + --message-expiration-time 7200 + ``` + +### 4. `--session-expiration-time`, `-s` + +- **Environment Variable:** `SESSION_EXPIRATION_TIME` +- **Default:** `3600` +- **Example:` + + ```sh + --session-expiration-time 14400 + ``` + +### 5. `--jwt-secret-key`, `-k` + +- **Environment Variable:** `JWT_SECRET_KEY` +- **Required:** Yes +- **Example:** + + ```sh + --jwt-secret-key "my_super_secret_key" + ``` + + +### 6. `--authorized-keys-path` + +- **Description:** The path to the JSON file containing authorized public keys. +- **Environment Variable:** `AUTHORIZED_KEYS_PATH` +- **Default:** `authorized_keys.json` +- **Example:** + + ```sh + --authorized-keys-path /path/to/authorized_keys.json + ``` + +### 7. `--authorized-keys` + +- **Description:** A comma-separated list of authorized public keys in hex format. +- **Environment Variable:** `AUTHORIZED_KEYS` +- **Type:** `Vec` +- **Example:** + + ```sh + --authorized-keys key1,key2,key3 + ``` + + This provides a list of authorized public keys directly on the command line or via environment variable. + +### 8. `--num-workes` + +- **Description:** The number of worker threads that the server should use for handling tasks. +- **Environment Variable:** `NUM_WORKES` +- **Default:** `4` +- **Example:** + + ```sh + --num-workes 8 + ``` + +### 9. `--admin-key` + +- **Description:** The key used for administrative access to the server. +- **Environment Variable:** `ADMIN_KEY` +- **Required:** Yes +- **Example:** + + ```sh + --admin-key "admin_super_secret_key" + ``` + + + +In this example, the server is configured to: + +- Listen on `127.0.0.1` at port `8080`. +- Use a message expiration time of `7200` seconds. +- Use a session expiration time of `14400` seconds. +- Sign JWTs with the provided `jwt-secret-key`. +- Load authorized keys from the specified file path and directly from the command line. +- Use `8` worker threads. +- Use the provided `admin-key` for administrative tasks. + +## Environment Variables + +All command-line options can also be set via environment variables. This is particularly useful in containerized or cloud environments where passing environment variables is preferred. + +## Getting Started + +To start the server, ensure you have the correct configuration and run it with the desired options. For more information on how to interact with the server, refer to the [SDK README](../prover-sdk/README.md) and the [Cairo-Prove README](../bin/cairo-prove/README.md). diff --git a/prover/src/auth/auth_errors.rs b/prover/src/auth/auth_errors.rs new file mode 100644 index 0000000..a353cd2 --- /dev/null +++ b/prover/src/auth/auth_errors.rs @@ -0,0 +1,34 @@ +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum AuthorizerError { + #[error("file read error")] + FileAccessError(#[from] std::io::Error), + #[error("invalid file format")] + FormatError(#[from] serde_json::Error), + #[error("Missing authorization header")] + MissingAuthorizationHeader, + #[error("Conversion from prefix hex failed: {0}")] + PrefixHexConversionError(String), + #[error(transparent)] + VerifyingKeyError(#[from] ed25519_dalek::SignatureError), + #[error("Unexpected data error: {0:?}")] + DataError(Vec), +} + +impl From> for AuthorizerError { + fn from(err: Vec) -> Self { + AuthorizerError::DataError(err) + } +} +#[derive(Error, Debug)] +pub enum AuthError { + #[error("Invalid token")] + InvalidToken, + + #[error("Missing authorization header")] + MissingAuthorizationHeader, + + #[error("Unauthorized")] + Unauthorized, +} diff --git a/prover/src/auth/authorizer.rs b/prover/src/auth/authorizer.rs index d45efb4..9516fb7 100644 --- a/prover/src/auth/authorizer.rs +++ b/prover/src/auth/authorizer.rs @@ -1,50 +1,32 @@ -use std::{collections::HashSet, path::PathBuf, sync::Arc}; - -use thiserror::Error; -use tokio::{fs::File, io::AsyncReadExt, sync::Mutex}; - -#[derive(Debug, Error)] -pub enum AuthorizerError { - #[error("file read error")] - FileAccessError(#[from] std::io::Error), - #[error("invalid file format")] - FormatError(#[from] serde_json::Error), -} +use super::auth_errors::AuthorizerError; +use ed25519_dalek::VerifyingKey; +use std::path::PathBuf; +use tokio::{fs::File, io::AsyncReadExt}; pub(crate) trait AuthorizationProvider { - async fn is_authorized(&self, public_key: &str) -> Result; - async fn authorize(&self, public_key: &str) -> Result<(), AuthorizerError>; + async fn is_authorized(&self, public_key: VerifyingKey) -> Result; + + async fn authorize(&self, public_key: VerifyingKey) -> Result<(), AuthorizerError>; } #[derive(Debug, Clone)] pub enum Authorizer { Open, Persistent(FileAuthorizer), - ReadOnlyFile(FileAuthorizer, MemoryAuthorizer), - Memory(MemoryAuthorizer), } impl AuthorizationProvider for Authorizer { - async fn is_authorized(&self, public_key: &str) -> Result { + async fn is_authorized(&self, public_key: VerifyingKey) -> Result { Ok(match self { Authorizer::Open => true, Authorizer::Persistent(authorizer) => authorizer.is_authorized(public_key).await?, - Authorizer::Memory(authorizer) => authorizer.is_authorized(public_key).await?, - Authorizer::ReadOnlyFile(file_authorizer, memory_authorizer) => { - memory_authorizer.is_authorized(public_key).await? - || file_authorizer.is_authorized(public_key).await? - } }) } - async fn authorize(&self, public_key: &str) -> Result<(), AuthorizerError> { + async fn authorize(&self, public_key: VerifyingKey) -> Result<(), AuthorizerError> { match self { Authorizer::Open => Ok(()), Authorizer::Persistent(authorizer) => authorizer.authorize(public_key).await, - Authorizer::Memory(authorizer) => authorizer.authorize(public_key).await, - Authorizer::ReadOnlyFile(_, memory_authorizer) => { - memory_authorizer.authorize(public_key).await - } } } } @@ -54,16 +36,20 @@ pub struct FileAuthorizer(PathBuf); impl FileAuthorizer { pub async fn new(path: PathBuf) -> Result { - File::open(&path) - .await - .map_err(AuthorizerError::FileAccessError)?; - + if !path.exists() { + tokio::fs::write(&path, "[]") + .await + .map_err(AuthorizerError::FileAccessError)?; + } else { + File::open(&path) + .await + .map_err(AuthorizerError::FileAccessError)?; + } Ok(Self(path)) } } - impl AuthorizationProvider for FileAuthorizer { - async fn is_authorized(&self, public_key: &str) -> Result { + async fn is_authorized(&self, public_key: VerifyingKey) -> Result { let mut file = File::open(&self.0) .await .map_err(AuthorizerError::FileAccessError)?; @@ -73,33 +59,51 @@ impl AuthorizationProvider for FileAuthorizer { .await .map_err(AuthorizerError::FileAccessError)?; - let authorized_keys: HashSet = serde_json::from_str::>(&contents) - .map_err(AuthorizerError::FormatError)? - .into_iter() - .collect(); + if contents.trim().is_empty() { + return Ok(false); + } + + let serialized_keys: Vec = + serde_json::from_str(&contents).map_err(AuthorizerError::FormatError)?; - Ok(authorized_keys.contains(public_key)) + for key in serialized_keys.iter() { + let verifying_key_bytes = prefix_hex::decode::>(key) + .map_err(|e| AuthorizerError::PrefixHexConversionError(e.to_string()))?; + let verifying_key = VerifyingKey::from_bytes(&verifying_key_bytes.try_into()?)?; + if verifying_key == public_key { + return Ok(true); + } + } + Ok(false) } - async fn authorize(&self, public_key: &str) -> Result<(), AuthorizerError> { + async fn authorize(&self, public_key: VerifyingKey) -> Result<(), AuthorizerError> { + let mut contents = String::new(); + let mut file = File::open(&self.0) .await .map_err(AuthorizerError::FileAccessError)?; - let mut contents = String::new(); file.read_to_string(&mut contents) .await .map_err(AuthorizerError::FileAccessError)?; - let mut authorized_keys: HashSet = serde_json::from_str::>(&contents) - .map_err(AuthorizerError::FormatError)? - .into_iter() - .collect(); - - authorized_keys.insert(public_key.into()); + let mut serialized_keys: Vec = + serde_json::from_str(&contents).unwrap_or_else(|_| Vec::new()); - let new_contents = - serde_json::to_string(&authorized_keys).map_err(AuthorizerError::FormatError)?; + for key in serialized_keys.iter() { + let verifying_key_bytes = prefix_hex::decode::>(key) + .map_err(|e| AuthorizerError::PrefixHexConversionError(e.to_string()))?; + let verifying_key = VerifyingKey::from_bytes(&verifying_key_bytes.try_into()?)?; + if verifying_key == public_key { + return Ok(()); + } + } + serialized_keys.push(prefix_hex::encode(public_key.to_bytes())); + let new_contents = serde_json::to_string(&serialized_keys) + .map_err(AuthorizerError::FormatError)? + .as_bytes() + .to_vec(); tokio::fs::write(&self.0, new_contents) .await @@ -108,38 +112,135 @@ impl AuthorizationProvider for FileAuthorizer { Ok(()) } } +#[cfg(test)] +mod tests { + use super::*; + use ed25519_dalek::{SigningKey, VerifyingKey}; + use rand::rngs::OsRng; + use tempfile::tempdir; + use tokio::fs; -#[derive(Debug, Clone)] -pub struct MemoryAuthorizer(Arc>>); + fn generate_signing_key() -> SigningKey { + SigningKey::generate(&mut OsRng) + } -impl AuthorizationProvider for MemoryAuthorizer { - async fn is_authorized(&self, public_key: &str) -> Result { - Ok(self.0.lock().await.contains(public_key)) + fn generate_verifying_key(signing_key: &SigningKey) -> VerifyingKey { + signing_key.verifying_key() } - async fn authorize(&self, public_key: &str) -> Result<(), AuthorizerError> { - self.0.lock().await.insert(public_key.into()); - Ok(()) + #[tokio::test] + async fn test_authorize_new_key_in_empty_file() { + let temp_dir = tempdir().unwrap(); + let file_path = temp_dir.path().join("authorized_keys.json"); + + let authorizer = FileAuthorizer::new(file_path.clone()).await.unwrap(); + + let signing_key = generate_signing_key(); + let public_key = generate_verifying_key(&signing_key); + authorizer.authorize(public_key).await.unwrap(); + + assert!(authorizer.is_authorized(public_key).await.unwrap()); + + temp_dir.close().unwrap(); } -} -impl From> for MemoryAuthorizer { - fn from(keys: Vec) -> Self { - Self(Arc::new(Mutex::new(keys.into_iter().collect()))) + #[tokio::test] + async fn test_authorize_existing_key() { + let temp_dir = tempdir().unwrap(); + let file_path = temp_dir.path().join("authorized_keys.json"); + + let authorizer = FileAuthorizer::new(file_path.clone()).await.unwrap(); + let signing_key = generate_signing_key(); + let public_key = generate_verifying_key(&signing_key); + authorizer.authorize(public_key).await.unwrap(); + + // Try authorizing the same key again + authorizer.authorize(public_key).await.unwrap(); + + // Verify the key is still authorized + assert!(authorizer.is_authorized(public_key).await.unwrap()); + + temp_dir.close().unwrap(); } -} -#[cfg(test)] -mod tests { - use super::*; + #[tokio::test] + async fn test_is_authorized_with_empty_file() { + let temp_dir = tempdir().unwrap(); + let file_path = temp_dir.path().join("authorized_keys.json"); + + // Create a new FileAuthorizer (this should create an empty file) + let authorizer = FileAuthorizer::new(file_path.clone()).await.unwrap(); + + // Generate a new key (but don't authorize it) + let signing_key = generate_signing_key(); + let public_key = generate_verifying_key(&signing_key); + // Verify that the key is not authorized + assert!(!authorizer.is_authorized(public_key).await.unwrap()); + + temp_dir.close().unwrap(); + } + + #[tokio::test] + async fn test_authorize_and_check_multiple_keys() { + let temp_dir = tempdir().unwrap(); + let file_path = temp_dir.path().join("authorized_keys.json"); + + let authorizer = FileAuthorizer::new(file_path.clone()).await.unwrap(); + + // Generate and authorize multiple keys + let mut keys = Vec::new(); + for _ in 0..5 { + let signing_key = generate_signing_key(); + let public_key = generate_verifying_key(&signing_key); + authorizer.authorize(public_key).await.unwrap(); + keys.push(public_key); + } + + // Verify all keys are authorized + for key in keys.iter() { + assert!(authorizer.is_authorized(*key).await.unwrap()); + } + + temp_dir.close().unwrap(); + } #[tokio::test] - async fn test_memory_authorizer() { - let authorizer = MemoryAuthorizer::from(vec!["test".into()]); + async fn test_authorize_with_prepopulated_keys() { + let temp_dir = tempdir().unwrap(); + let file_path = temp_dir.path().join("authorized_keys.json"); + + // Prepopulate the file with some keys + let mut initial_keys = Vec::new(); + for _ in 0..3 { + let signing_key = generate_signing_key(); + let public_key = generate_verifying_key(&signing_key); + initial_keys.push(prefix_hex::encode(public_key.to_bytes())); + } + + // Serialize the keys and write them to the file + let serialized_keys = serde_json::to_string(&initial_keys).unwrap(); + fs::write(&file_path, serialized_keys).await.unwrap(); + + // Create a FileAuthorizer that will use the prepopulated file + let authorizer = FileAuthorizer::new(file_path.clone()).await.unwrap(); + + // Verify that the initial keys are authorized + for encoded_key in &initial_keys { + let verifying_key_bytes = prefix_hex::decode::>(encoded_key).unwrap(); + let verifying_key = + VerifyingKey::from_bytes(&verifying_key_bytes.try_into().unwrap()).unwrap(); + assert!(authorizer.is_authorized(verifying_key).await.unwrap()); + } + + // Add a new key and verify it + let new_signing_key = generate_signing_key(); + let new_public_key = generate_verifying_key(&new_signing_key); + authorizer.authorize(new_public_key).await.unwrap(); + + // Verify that the new key is authorized + assert!(authorizer.is_authorized(new_public_key).await.unwrap()); - assert!(authorizer.is_authorized("test").await.unwrap()); - assert!(!authorizer.is_authorized("test2").await.unwrap()); - authorizer.authorize("test2").await.unwrap(); - assert!(authorizer.is_authorized("test2").await.unwrap()); + // Clean up + temp_dir.close().unwrap(); } } diff --git a/prover/src/auth/jwt.rs b/prover/src/auth/jwt.rs index 371383f..152eade 100644 --- a/prover/src/auth/jwt.rs +++ b/prover/src/auth/jwt.rs @@ -1,21 +1,16 @@ -use crate::prove::errors::{AuthError, ProveError}; -use crate::server::AppState; -use axum::extract::FromRef; -use axum::{async_trait, extract::FromRequestParts, http::header::COOKIE, http::request::Parts}; +use std::{collections::HashMap, fmt::Display}; + +use axum::{ + async_trait, + extract::{FromRef, FromRequestParts}, + http::{header::COOKIE, request::Parts}, +}; +use ed25519_dalek::VerifyingKey; use jsonwebtoken::{decode, encode, DecodingKey, EncodingKey, Header, Validation}; use serde::{Deserialize, Serialize}; -use std::collections::HashMap; -use std::fmt::Display; use tracing::warn; -pub fn encode_jwt(sub: &str, exp: usize, keys: Keys) -> Result { - let claims = Claims { - sub: sub.to_owned(), - exp, - }; - encode(&Header::default(), &claims, &keys.encoding) - .map_err(|e| ProveError::InternalServerError(format!("JWT generation failed: {}", e))) -} +use crate::{auth::auth_errors::AuthError, errors::ProverError, server::AppState}; #[async_trait] impl FromRequestParts for Claims @@ -23,26 +18,27 @@ where AppState: FromRef, S: Send + Sync, { - type Rejection = ProveError; + type Rejection = ProverError; async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result { let store: AppState = AppState::from_ref(_state); // Extract the 'Cookie' header - let header_value = parts.headers.get(COOKIE).ok_or_else(|| { - warn!("Missing 'Cookie' header in the request"); - ProveError::Auth(AuthError::MissingAuthorizationHeader) - })?; - // Convert the header value to a string - let cookie_str = header_value + let cookie_str = parts + .headers + .get(COOKIE) + .ok_or_else(|| { + warn!("Missing 'Cookie' header in the request"); + ProverError::Auth(AuthError::MissingAuthorizationHeader) + })? .to_str() - .map_err(|_| ProveError::Auth(AuthError::InvalidToken))?; + .map_err(|_| ProverError::Auth(AuthError::InvalidToken))?; // Parse the cookie string into a HashMap let cookies: HashMap<_, _> = cookie_str .split(';') - .filter_map(|s| { - let mut parts = s.split('='); + .filter_map(|cookie| { + let mut parts = cookie.split('='); match (parts.next(), parts.next()) { (Some(key), Some(value)) => Some((key.trim(), value.trim())), _ => None, @@ -53,14 +49,14 @@ where // Extract the JWT token from the cookies let token = cookies .get("jwt_token") - .ok_or(ProveError::Auth(AuthError::MissingAuthorizationHeader))?; + .ok_or(ProverError::Auth(AuthError::MissingAuthorizationHeader))?; let token_data = decode::( token, &Keys::new(&store.jwt_secret_key.into_bytes()).decoding, &Validation::default(), ) - .map_err(|_| ProveError::Auth(AuthError::InvalidToken))?; + .map_err(|_| ProverError::Auth(AuthError::InvalidToken))?; Ok(token_data.claims) } @@ -69,6 +65,7 @@ where pub struct Claims { pub sub: String, pub exp: usize, + pub session_key: VerifyingKey, } impl Display for Claims { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { @@ -88,3 +85,17 @@ impl Keys { } } } +pub fn encode_jwt( + sub: &str, + exp: usize, + keys: Keys, + session_key: VerifyingKey, +) -> Result { + let claims = Claims { + sub: sub.to_owned(), + exp, + session_key, + }; + encode(&Header::default(), &claims, &keys.encoding) + .map_err(|e| ProverError::InternalServerError(format!("JWT generation failed: {}", e))) +} diff --git a/prover/src/auth/mod.rs b/prover/src/auth/mod.rs index 7e1d11a..513904d 100644 --- a/prover/src/auth/mod.rs +++ b/prover/src/auth/mod.rs @@ -1,71 +1,22 @@ -use axum::{routing::get, routing::post, Router}; - -use crate::server::AppState; - +pub mod auth_errors; pub mod authorizer; pub mod jwt; +pub mod nonce; +pub mod register; pub mod validation; - -pub fn auth(app_state: &AppState) -> Router { +use crate::server::AppState; +use axum::{ + routing::{get, post}, + Router, +}; +use nonce::generate_nonce; +use register::register; +use validation::validate_signature; + +pub fn auth(app_state: AppState) -> Router { Router::new() - .route("/auth", get(crate::auth::validation::generate_nonce)) - .route("/auth", post(crate::auth::validation::validate_signature)) - .route( - "/register", - post(crate::auth::validation::add_authorized_key), - ) + .route("/auth", get(generate_nonce)) + .route("/auth", post(validate_signature)) + .route("/register", post(register)) .with_state(app_state.clone()) } - -#[cfg(test)] -mod tests { - - use crate::auth::authorizer::Authorizer; - use crate::auth::validation::generate_nonce; - - use crate::prove::errors::ProveError; - use crate::prove::models::GenerateNonceRequest; - - use crate::server::AppState; - - use axum::extract::Query; - use axum::extract::State; - - use ed25519_dalek::SigningKey; - use std::collections::HashMap; - use std::sync::Arc; - use std::sync::Mutex; - - #[tokio::test] - async fn test_generate_nonce() -> Result<(), ProveError> { - let private_key_hex: String = - r#"0xf91350db1ca372b54376b519be8bf73a7bbbbefc4ffe169797bc3f5ea2dec740"#.to_string(); - let private_key_bytes: Vec = prefix_hex::decode(&private_key_hex) - .map_err(|err| ProveError::HexDecodeError(err.to_string()))?; - let mut private_key_array = [0u8; 32]; - private_key_array.copy_from_slice(&private_key_bytes[..32]); // Copy the first 32 bytes - let signing_key: SigningKey = SigningKey::from_bytes(&private_key_array); - let public_key = signing_key.verifying_key(); - let encoded_verifying_key: Vec = public_key.to_bytes().to_vec(); - let public_key_hex: String = prefix_hex::encode(&encoded_verifying_key); - - let state = AppState { - nonces: Arc::new(Mutex::new(HashMap::new())), - prover_image_name: "sample".to_string(), - message_expiration_time: 3600, - session_expiration_time: 3600, - jwt_secret_key: "jwt_secret".to_string(), - authorizer: Authorizer::Memory(vec![public_key_hex.clone()].into()), - }; - let params = GenerateNonceRequest { - public_key: public_key_hex, - }; - let result = generate_nonce(State(state), Query(params)).await; - - assert!(result.is_ok()); - - let _response = result.unwrap(); - - Ok(()) - } -} diff --git a/prover/src/prove/models.rs b/prover/src/auth/nonce.rs similarity index 52% rename from prover/src/prove/models.rs rename to prover/src/auth/nonce.rs index eee0514..89a93ac 100644 --- a/prover/src/prove/models.rs +++ b/prover/src/auth/nonce.rs @@ -1,4 +1,13 @@ +use super::authorizer::AuthorizationProvider; +use crate::server::AppState; +use crate::{auth::auth_errors::AuthError, errors::ProverError}; +use axum::{ + extract::{Query, State}, + Json, +}; use bytes::{Bytes, BytesMut}; +use common::requests::GenerateNonceRequest; +use ed25519_dalek::VerifyingKey; use rand::RngCore; use serde::{Deserialize, Serialize}; use serde_with::{serde_as, DisplayFromStr}; @@ -22,7 +31,6 @@ impl Nonce { Self(bytes.into()) } } - impl FromStr for Nonce { type Err = io::Error; @@ -48,21 +56,24 @@ impl Deref for Nonce { &self.0 } } - -#[derive(Debug, Serialize, Deserialize)] -pub struct GenerateNonceRequest { - pub public_key: String, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct PublicKeyQuery { - pub public_key: String, -} - -#[serde_as] -#[derive(Debug, Serialize, Deserialize)] -pub struct JWTResponse { - #[serde_as(as = "DisplayFromStr")] - pub jwt_token: String, - pub expiration: usize, +pub async fn generate_nonce( + State(state): State, + Query(params): Query, +) -> Result, ProverError> { + let key: VerifyingKey = serde_json::from_str(¶ms.public_key)?; + if !state.authorizer.is_authorized(key).await? { + return Err(ProverError::Auth(AuthError::Unauthorized)); + } + tracing::info!("Authorized"); + let message_expiration_time: usize = state.message_expiration_time; + let nonce: Nonce = Nonce::new(32); + let noce_string = nonce.to_string(); + let mut nonces = state.nonces.lock().await; + nonces.insert(noce_string, key); + drop(nonces); + tracing::info!("Nonce generated: {}", nonce); + Ok(Json(GenerateNonceResponse { + nonce, + expiration: message_expiration_time, + })) } diff --git a/prover/src/auth/register.rs b/prover/src/auth/register.rs new file mode 100644 index 0000000..0989e6f --- /dev/null +++ b/prover/src/auth/register.rs @@ -0,0 +1,21 @@ +use axum::{extract::State, response::IntoResponse, Json}; +use common::requests::AddKeyRequest; + +use crate::{errors::ProverError, server::AppState}; + +use super::{auth_errors::AuthError, authorizer::AuthorizationProvider, jwt::Claims}; + +pub async fn register( + State(state): State, + _claims: Claims, + Json(payload): Json, +) -> Result { + if state.admin_key != payload.authority { + return Err(ProverError::Auth(AuthError::Unauthorized)); + } + payload + .authority + .verify_strict(payload.new_key.as_bytes(), &payload.signature)?; + state.authorizer.authorize(payload.new_key).await?; + Ok(()) +} diff --git a/prover/src/auth/validation.rs b/prover/src/auth/validation.rs index 65f3e46..9f093a7 100644 --- a/prover/src/auth/validation.rs +++ b/prover/src/auth/validation.rs @@ -1,207 +1,258 @@ -use crate::auth::jwt::encode_jwt; -use crate::auth::jwt::Keys; -use crate::prove::errors::ProveError; -use crate::prove::models::{GenerateNonceRequest, GenerateNonceResponse, JWTResponse, Nonce}; -use crate::server::AppState; +use super::jwt::{encode_jwt, Keys}; +use crate::{errors::ProverError, server::AppState}; use axum::{ - extract::{Json, Query, State}, - http::{self, HeaderMap, HeaderValue}, + extract::State, + http::{header::SET_COOKIE, HeaderMap, HeaderValue}, response::IntoResponse, + Json, }; -use common::AddAuthorizedRequest; -use common::ValidateSignatureRequest; -use ed25519_dalek::Signature; -use ed25519_dalek::VerifyingKey; -use std::collections::HashSet; -use tokio::{fs::File, io::AsyncReadExt}; - -use super::authorizer::AuthorizationProvider; +use common::{models::JWTResponse, requests::ValidateSignatureRequest}; +use ed25519_dalek::Verifier; pub const COOKIE_NAME: &str = "jwt_token"; -/// Generates a nonce for a given public key and stores it in the application state. -/// -/// # Parameters -/// -/// - `state`: The application state containing a mutex-guarded HashMap to store nonces. -/// - `params`: The query parameters containing the public key for which nonce is generated. -/// -/// # Returns -/// -/// Returns a JSON response containing the generated nonce and its expiration time, or -/// an error if the public key is missing. -pub async fn generate_nonce( - State(state): State, - Query(params): Query, -) -> Result, ProveError> { - if params.public_key.trim().is_empty() { - return Err(ProveError::MissingPublicKey); - } - if !state.authorizer.is_authorized(¶ms.public_key).await? { - return Err(ProveError::UnauthorizedPublicKey); - } - - let message_expiration_time: usize = state.message_expiration_time; - let nonce: Nonce = Nonce::new(32); - let nonce_string = nonce.to_string(); - let mut nonces: std::sync::MutexGuard<'_, std::collections::HashMap> = - state.nonces.lock().unwrap(); - let formatted_key = params.public_key.trim().to_lowercase(); - - nonces.insert(formatted_key.clone(), nonce_string); - - Ok(Json(GenerateNonceResponse { - nonce, - expiration: message_expiration_time, - })) -} - -/// Validates the signature provided in the request payload and generates a JWT token if the signature is valid. -/// -/// # Parameters -/// -/// - `state`: The application state containing nonce information stored in a mutex-guarded HashMap. -/// - `payload`: JSON payload containing the public key and signature to be validated. -/// pub async fn validate_signature( State(state): State, Json(payload): Json, -) -> Result { - let encoded_key = prefix_hex::encode(payload.public_key.to_bytes()); - - if !state.authorizer.is_authorized(&encoded_key).await? { - return Err(ProveError::UnauthorizedPublicKey); +) -> Result { + tracing::info!("Validating signature"); + let nonces = state.nonces.lock().await; + let public_key = nonces.get(&payload.message.nonce); + let public_key = match public_key { + Some(public_key) => public_key, + None => { + return Err(ProverError::CustomError( + "Public key for nonce not found".to_string(), + )) + } + }; + tracing::info!("Public key found for nonce"); + let encoded_public_key = prefix_hex::encode(public_key.to_bytes()); + let serialized_message = serde_json::to_string(&payload.message)?; + let verification = public_key + .verify(serialized_message.as_bytes(), &payload.signature) + .is_ok(); + if !verification { + return Err(ProverError::CustomError("Signature is invalid".to_string())); } - - let session_expiration_time: usize = state.session_expiration_time; - - let nonces = state - .nonces - .lock() - .map_err(|_| ProveError::InternalServerError("Failed to lock state".to_string()))?; - - let user_nonce = nonces.get(&encoded_key).ok_or_else(|| { - ProveError::NotFound(format!( - "Nonce not found for the provided public key: {}", - &encoded_key - )) - })?; - - payload - .public_key - .verify_strict(user_nonce.as_bytes(), &payload.signature) - .map_err(ProveError::Unauthorized)?; - - let expiration = chrono::Utc::now() + chrono::Duration::seconds(session_expiration_time as i64); + tracing::info!("Signature is valid"); + let expiration = + chrono::Utc::now() + chrono::Duration::seconds(state.message_expiration_time as i64); let token = encode_jwt( - &encoded_key, + &encoded_public_key, expiration.timestamp() as usize, Keys::new(state.jwt_secret_key.clone().as_bytes()), - ) - .map_err(|_| ProveError::InternalServerError("JWT generation failed".to_string()))?; + payload.message.session_key, + )?; + tracing::info!("JWT token generated"); let cookie_value = format!( "{}={}; HttpOnly; Secure; Path=/; Max-Age={}", - COOKIE_NAME, token, session_expiration_time + COOKIE_NAME, token, state.session_expiration_time ); let mut headers = HeaderMap::new(); headers.insert( - http::header::SET_COOKIE, - HeaderValue::from_str(&cookie_value).map_err(|_| { - ProveError::InternalServerError("Failed to set cookie header".to_string()) - })?, + SET_COOKIE, + HeaderValue::from_str(&cookie_value) + .map_err(|_| ProverError::CustomError("Invalid cookie value".to_string()))?, ); - + tracing::info!("Cookie set"); Ok(( headers, Json(JWTResponse { jwt_token: token, - expiration: session_expiration_time, + expiration: expiration.timestamp() as u64, + session_key: Some(payload.message.session_key), }), )) } +#[cfg(test)] +mod tests { + use std::{collections::HashMap, sync::Arc}; -/// Validates the signature provided in the request payload and generates a JWT token if the signature is valid. -/// -/// # Parameters -/// -/// - `state`: The application state containing nonce information stored in a mutex-guarded HashMap. -/// - `payload`: JSON payload containing the public key to be added and the signature to be validated. -/// -/// # Returns -/// -/// Returns a tuple containing HTTP headers and a JSON response with a JWT token and its expiration time if the signature is valid. -pub async fn add_authorized_key( - State(state): State, - Json(payload): Json, -) -> Result { - let encoded_key = prefix_hex::encode(payload.new_key.to_bytes()); - - // if !state.authorizer.is_authorized(&encoded_key).await? { - // return Err(ProveError::UnauthorizedPublicKey); - // } - - // payload - // .authority - // .verify_strict(payload.new_key.as_bytes(), &payload.signature) - // .map_err(ProveError::Unauthorized)?; - - state - .authorizer - .authorize(&encoded_key) - .await - .map_err(|_| ProveError::InternalServerError("Failed to authorize key".to_string()))?; - - Ok(()) -} + use axum::extract::State; + use axum::Json; + use common::requests::{Message, ValidateSignatureRequest}; + use ed25519_dalek::{Signature, Signer, SigningKey, VerifyingKey}; + use rand::rngs::OsRng; + use tokio::sync::Mutex; -/// Verifies a signature given a nonce and a public key using ed25519_dalek. -/// -/// - `signature`: The signature object. -/// - `nonce`: The message that was signed, as a string. -/// - `public_key_hex`: The hexadecimal string of the public key. -/// -/// Returns `true` if the signature is valid; `false` otherwise. -pub fn verify_signature(signature: &Signature, nonce: &str, public_key_hex: &str) -> bool { - let public_key_bytes = match prefix_hex::decode::>(public_key_hex) { - Ok(bytes) => bytes, - Err(_) => return false, + use crate::{ + auth::{authorizer::Authorizer, nonce::Nonce, validate_signature}, + errors::ProverError, + server::AppState, + threadpool::ThreadPool, }; - let mut public_key_array = [0u8; 32]; - public_key_array.copy_from_slice(&public_key_bytes[..32]); // Copy the first 32 bytes + fn generate_signing_key() -> SigningKey { + SigningKey::generate(&mut OsRng) + } - let public_key = match VerifyingKey::from_bytes(&public_key_array) { - Ok(pk) => pk, - Err(_) => return false, - }; + fn generate_verifying_key(signing_key: &SigningKey) -> VerifyingKey { + signing_key.verifying_key() + } - public_key - .verify_strict(nonce.as_bytes(), signature) - .is_ok() -} + #[tokio::test] + async fn test_valid_signature() { + let nonce = Nonce::new(32); + let nonce_string = nonce.to_string(); + let private_key = generate_signing_key(); + let public_key = generate_verifying_key(&private_key); + let session_private_key = generate_signing_key(); + let session_public_key = generate_verifying_key(&session_private_key); + let message = Message { + session_key: session_public_key, + nonce: nonce_string.clone(), + }; + let signed_message = private_key.sign(serde_json::to_string(&message).unwrap().as_bytes()); + let payload = ValidateSignatureRequest { + message, + signature: signed_message, + }; + let nonces: Arc>> = + Arc::new(Mutex::new(HashMap::new())); + nonces.lock().await.insert(nonce_string.clone(), public_key); + + let app_state = AppState { + jwt_secret_key: "secret".to_string(), + job_store: Default::default(), + message_expiration_time: 100, + session_expiration_time: 100, + thread_pool: Arc::new(Mutex::new(ThreadPool::new(1))), + nonces, + authorizer: Authorizer::Open, + admin_key: generate_verifying_key(&generate_signing_key()), + sse_tx: Arc::new(Mutex::new(tokio::sync::broadcast::channel(100).0)), + }; + + let result = validate_signature(State(app_state), Json(payload)).await; + + assert!(result.is_ok()); + } + + #[tokio::test] + async fn test_invalid_signature() { + let nonce = Nonce::new(32); + let nonce_string = nonce.to_string(); + let signing_private_key = generate_signing_key(); + let false_private_key = generate_signing_key(); + let false_public_key = generate_verifying_key(&false_private_key); + let session_private_key = generate_signing_key(); + let session_public_key = generate_verifying_key(&session_private_key); + let message = Message { + session_key: session_public_key, + nonce: nonce_string.clone(), + }; + let signed_message = + signing_private_key.sign(serde_json::to_string(&message).unwrap().as_bytes()); + let payload = ValidateSignatureRequest { + message, + signature: signed_message, + }; + let nonces: Arc>> = + Arc::new(Mutex::new(HashMap::new())); + nonces + .lock() + .await + .insert(nonce_string.clone(), false_public_key); + + let app_state = AppState { + jwt_secret_key: "secret".to_string(), + job_store: Default::default(), + message_expiration_time: 100, + session_expiration_time: 100, + thread_pool: Arc::new(Mutex::new(ThreadPool::new(1))), + nonces, + authorizer: Authorizer::Open, + admin_key: generate_verifying_key(&generate_signing_key()), + sse_tx: Arc::new(Mutex::new(tokio::sync::broadcast::channel(100).0)), + }; + + let result = validate_signature(State(app_state), Json(payload)).await; + assert!(result.is_err()); + if let Err(ProverError::CustomError(message)) = result { + assert_eq!(message, "Signature is invalid".to_string()); + } else { + panic!("Unexpected error type"); + } + } + + #[tokio::test] + async fn test_nonce_not_found() { + let nonce = Nonce::new(32); + let nonce_string = nonce.to_string(); + let private_key = generate_signing_key(); + let session_private_key = generate_signing_key(); + let session_public_key = generate_verifying_key(&session_private_key); + let message = Message { + session_key: session_public_key, + nonce: nonce_string.clone(), + }; + let signed_message = private_key.sign(serde_json::to_string(&message).unwrap().as_bytes()); + let payload = ValidateSignatureRequest { + message, + signature: signed_message, + }; + let nonces: Arc>> = + Arc::new(Mutex::new(HashMap::new())); // Empty nonces map + + let app_state = AppState { + jwt_secret_key: "secret".to_string(), + job_store: Default::default(), + message_expiration_time: 100, + session_expiration_time: 100, + thread_pool: Arc::new(Mutex::new(ThreadPool::new(1))), + nonces, + authorizer: Authorizer::Open, + admin_key: generate_verifying_key(&generate_signing_key()), + sse_tx: Arc::new(Mutex::new(tokio::sync::broadcast::channel(100).0)), + }; + + let result = validate_signature(State(app_state), Json(payload)).await; + assert!(result.is_err()); + if let Err(ProverError::CustomError(message)) = result { + assert_eq!(message, "Public key for nonce not found".to_string()); + } else { + panic!("Unexpected error type"); + } + } + + #[tokio::test] + async fn test_missing_signature() { + let nonce = Nonce::new(32); + let nonce_string = nonce.to_string(); + let public_key = generate_verifying_key(&generate_signing_key()); + let session_private_key = generate_signing_key(); + let session_public_key = generate_verifying_key(&session_private_key); + let message = Message { + session_key: session_public_key, + nonce: nonce_string.clone(), + }; + + let payload = ValidateSignatureRequest { + message, + signature: Signature::from_bytes(&[0; 64]), // Invalid signature + }; + let nonces: Arc>> = + Arc::new(Mutex::new(HashMap::new())); + nonces.lock().await.insert(nonce_string.clone(), public_key); + + let app_state = AppState { + jwt_secret_key: "secret".to_string(), + job_store: Default::default(), + message_expiration_time: 100, + session_expiration_time: 100, + thread_pool: Arc::new(Mutex::new(ThreadPool::new(1))), + nonces, + authorizer: Authorizer::Open, + admin_key: generate_verifying_key(&generate_signing_key()), + sse_tx: Arc::new(Mutex::new(tokio::sync::broadcast::channel(100).0)), + }; -/// Reads the authorized keys from the `authorized_keys.json` file and returns them as a HashSet. -/// -/// # Returns -/// -/// Returns a HashSet containing the authorized keys, or an error if reading the file fails. -pub async fn is_public_key_authorized(path: &str, public_key: &str) -> Result<(), ProveError> { - let formatted_key = public_key.trim().to_lowercase(); - - // Read the authorized_keys.json file - let mut file = File::open(path).await.map_err(ProveError::FileReadError)?; - let mut contents = String::new(); - - file.read_to_string(&mut contents) - .await - .map_err(ProveError::FileReadError)?; - - let authorized_keys: HashSet = serde_json::from_str::>(&contents) - .map_err(|_| ProveError::JsonParsingFailed("authorized_keys.json".to_string()))? - .into_iter() - .collect(); - - if !authorized_keys.contains(&formatted_key) { - return Err(ProveError::UnauthorizedPublicKey); + let result = validate_signature(State(app_state), Json(payload)).await; + assert!(result.is_err()); + if let Err(ProverError::CustomError(message)) = result { + assert_eq!(message, "Signature is invalid".to_string()); + } else { + panic!("Unexpected error type"); + } } - Ok(()) } diff --git a/prover/src/errors.rs b/prover/src/errors.rs new file mode 100644 index 0000000..7d36f67 --- /dev/null +++ b/prover/src/errors.rs @@ -0,0 +1,81 @@ +use axum::{ + http::StatusCode, + response::{IntoResponse, Response}, + Json, +}; +use serde_json::json; +use std::{convert::Infallible, net::AddrParseError}; +use thiserror::Error; +use tokio::sync::mpsc::error::SendError; + +use crate::auth::auth_errors::{AuthError, AuthorizerError}; + +#[derive(Debug, Error)] +pub enum ProverError { + #[error(transparent)] + Parse(#[from] serde_json::Error), + #[error(transparent)] + FileWriteError(#[from] std::io::Error), + #[error(transparent)] + InfallibleError(#[from] Infallible), + #[error("{0}")] + CustomError(String), + #[error("Failed to send message{0}")] + SendError(String), + #[error(transparent)] + Auth(#[from] AuthError), + #[error("Internal server error{0}")] + InternalServerError(String), + #[error(transparent)] + Authorizer(#[from] AuthorizerError), + #[error(transparent)] + AddressParse(#[from] AddrParseError), + #[error(transparent)] + KeyError(#[from] ed25519_dalek::SignatureError), +} +impl From> for ProverError { + fn from(err: SendError) -> ProverError { + ProverError::SendError(err.to_string()) + } +} +impl IntoResponse for ProverError { + fn into_response(self) -> Response { + let (status, error_message) = match &self { + ProverError::FileWriteError(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), + ProverError::Parse(e) => (StatusCode::BAD_REQUEST, e.to_string()), + ProverError::InfallibleError(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), + ProverError::CustomError(e) => (StatusCode::BAD_REQUEST, e.to_string()), + ProverError::SendError(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), + ProverError::Auth(e) => match e { + AuthError::InvalidToken => (StatusCode::BAD_REQUEST, e.to_string()), + AuthError::MissingAuthorizationHeader => (StatusCode::BAD_REQUEST, e.to_string()), + AuthError::Unauthorized => (StatusCode::UNAUTHORIZED, e.to_string()), + }, + ProverError::InternalServerError(e) => { + (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()) + } + ProverError::Authorizer(authorizer_error) => match authorizer_error { + AuthorizerError::FileAccessError(e) => { + (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()) + } + AuthorizerError::FormatError(e) => (StatusCode::BAD_REQUEST, e.to_string()), + AuthorizerError::MissingAuthorizationHeader => { + (StatusCode::BAD_REQUEST, authorizer_error.to_string()) + } + AuthorizerError::PrefixHexConversionError(e) => { + (StatusCode::BAD_REQUEST, e.to_string()) + } + AuthorizerError::VerifyingKeyError(e) => (StatusCode::BAD_REQUEST, e.to_string()), + AuthorizerError::DataError(_e) => ( + StatusCode::INTERNAL_SERVER_ERROR, + "Conversion to Vec failed".to_string(), + ), + }, + ProverError::AddressParse(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), + ProverError::KeyError(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), + }; + + let body = Json(json!({ "error": error_message })); + (status, body).into_response() + } +} diff --git a/prover/src/extractors/mod.rs b/prover/src/extractors/mod.rs new file mode 100644 index 0000000..2d5ea29 --- /dev/null +++ b/prover/src/extractors/mod.rs @@ -0,0 +1 @@ +pub mod workdir; diff --git a/prover/src/extractors/workdir.rs b/prover/src/extractors/workdir.rs new file mode 100644 index 0000000..233493d --- /dev/null +++ b/prover/src/extractors/workdir.rs @@ -0,0 +1,27 @@ +use axum::{async_trait, extract::FromRequestParts, http::request::Parts, response::Response}; +use tempfile::TempDir; + +pub struct TempDirHandle(pub TempDir); + +impl Clone for TempDirHandle { + fn clone(&self) -> Self { + TempDirHandle(TempDir::new().expect("failed to create temp dir")) + } +} + +#[async_trait] +impl FromRequestParts for TempDirHandle +where + S: Send + Sync, +{ + type Rejection = Response; + async fn from_request_parts(_req: &mut Parts, _state: &S) -> Result { + let temp_dir = TempDir::new().map_err(|_| { + Response::builder() + .status(500) + .body("Failed to create temp dir".into()) + .unwrap() + })?; + Ok(TempDirHandle(temp_dir)) + } +} diff --git a/prover/src/lib.rs b/prover/src/lib.rs index 3bc9286..b25cb20 100644 --- a/prover/src/lib.rs +++ b/prover/src/lib.rs @@ -1,30 +1,35 @@ pub mod auth; +pub mod errors; +pub mod extractors; pub mod prove; pub mod server; +pub mod sse; +pub mod threadpool; +pub mod utils; pub mod verifier; use std::path::PathBuf; -use clap::{arg, Parser, ValueHint}; +use clap::{arg, Parser}; -/// Command line arguments for the server #[derive(Parser, Debug)] #[clap(author, version, about, long_about = None)] pub struct Args { - /// Host address to bind the server #[arg(long, env, default_value = "0.0.0.0")] pub host: String, - - /// Port to listen on #[arg(long, short, env, default_value = "3000")] pub port: u16, + #[arg(long, short, env, default_value = "3600")] + pub message_expiration_time: usize, + #[arg(long, short, env, default_value = "3600")] + pub session_expiration_time: usize, #[arg(long, short, env)] pub jwt_secret_key: String, - #[arg(long, short, env)] - pub message_expiration_time: u32, - #[arg(long, short, env)] - pub session_expiration_time: u32, - #[arg(long, short, env, value_hint = ValueHint::FilePath)] - pub authorized_keys_path: Option, - #[arg(long, short = 'f', env, value_delimiter = ',')] - pub authorized_keys: Option>, + #[arg(long, env, default_value = "authorized_keys.json")] + pub authorized_keys_path: PathBuf, + #[arg(long, env, value_delimiter = ',')] + pub authorized_keys: Vec, + #[arg(long, env, default_value = "4")] + pub num_workes: usize, + #[arg(long, env)] + pub admin_key: String, } diff --git a/prover/src/main.rs b/prover/src/main.rs index da6ad54..827af26 100644 --- a/prover/src/main.rs +++ b/prover/src/main.rs @@ -1,14 +1,8 @@ use clap::Parser; -use prover::prove::errors::ServerError; -use prover::server::start; -use prover::Args; - +use prover::{errors::ProverError, server::start, Args}; #[tokio::main] -async fn main() -> Result<(), ServerError> { - let args: Args = Args::parse(); - - // Start the server with the specified address +async fn main() -> Result<(), ProverError> { + let args = Args::parse(); start(args).await?; - Ok(()) } diff --git a/prover/src/prove/cairo.rs b/prover/src/prove/cairo.rs new file mode 100644 index 0000000..7933bd0 --- /dev/null +++ b/prover/src/prove/cairo.rs @@ -0,0 +1,36 @@ +use crate::auth::jwt::Claims; +use crate::extractors::workdir::TempDirHandle; +use crate::server::AppState; +use crate::threadpool::CairoVersionedInput; +use crate::utils::job::create_job; +use axum::Json; +use axum::{extract::State, http::StatusCode, response::IntoResponse}; +use common::cairo_prover_input::CairoProverInput; +use serde_json::json; + +pub async fn root( + State(app_state): State, + TempDirHandle(path): TempDirHandle, + _claims: Claims, + Json(program_input): Json, +) -> impl IntoResponse { + let thread_pool = app_state.thread_pool.clone(); + let job_store = app_state.job_store.clone(); + let job_id = create_job(&job_store).await; + let thread = thread_pool.lock().await; + thread + .execute( + job_id, + job_store, + path, + CairoVersionedInput::Cairo(program_input), + app_state.sse_tx.clone(), + ) + .await + .into_response(); + + let body = json!({ + "job_id": job_id + }); + (StatusCode::ACCEPTED, body.to_string()) +} diff --git a/prover/src/prove/cairo0.rs b/prover/src/prove/cairo0.rs index ea0da5f..4860382 100644 --- a/prover/src/prove/cairo0.rs +++ b/prover/src/prove/cairo0.rs @@ -1,95 +1,35 @@ use crate::auth::jwt::Claims; -use crate::prove::errors::ProveError; +use crate::extractors::workdir::TempDirHandle; +use crate::server::AppState; +use crate::threadpool::CairoVersionedInput; +use crate::utils::job::create_job; use axum::Json; -use common::Cairo0ProverInput; -use config_generator::generate_config; -use serde_json::Value; -use std::{ - path::{Path, PathBuf}, - process::Command, -}; -use tokio::fs; +use axum::{extract::State, http::StatusCode, response::IntoResponse}; +use common::cairo0_prover_input::Cairo0ProverInput; +use serde_json::json; pub async fn root( + State(app_state): State, + TempDirHandle(path): TempDirHandle, _claims: Claims, Json(program_input): Json, -) -> Result { - let program_input_path: PathBuf = Path::new("resources/cairoZero/input.json").to_path_buf(); - let program_path: PathBuf = Path::new("resources/cairoZero/program.json").to_path_buf(); - let proof_path: PathBuf = Path::new("program_proof_cairo0.json").to_path_buf(); - let trace_file = Path::new("resources/cairoZero/program_trace.trace").to_path_buf(); - let memory_file = Path::new("resources/cairoZero/program_memory.memory").to_path_buf(); - let public_input_file = - Path::new("resources/cairoZero/program_public_input.json").to_path_buf(); - let private_input_file = - Path::new("resources/cairoZero/program_private_input.json").to_path_buf(); - let params_file = Path::new("resources/cairoZero/cpu_air_params.json").to_path_buf(); - let config_file = Path::new("config/cpu_air_prover_config.json").to_path_buf(); - - let input = serde_json::to_string(&program_input.program_input)?; - let program = serde_json::to_string(&program_input.program)?; - let layout = program_input.layout; - - fs::write(&program_input_path, input.clone()).await?; - fs::write(&program_path, program.clone()).await?; - - //run cairo-run - let mut command = Command::new("cairo-run"); - command - .arg("--trace_file") - .arg(&trace_file) - .arg("--memory_file") - .arg(&memory_file) - .arg("--layout") - .arg(layout) - .arg("--proof_mode") - .arg("--air_public_input") - .arg(&public_input_file) - .arg("--air_private_input") - .arg(&private_input_file) - .arg("--program_input") - .arg(&program_input_path) - .arg("--program") - .arg(&program_path); - - let mut child = command.spawn()?; - let _status = child.wait()?; - - generate_config::generate( - "resources/cairoZero/program_public_input.json", - "resources/cairoZero/cpu_air_params.json", - ); - - //run cpu_air_prover - let mut command_proof = Command::new("cpu_air_prover"); - command_proof - .arg("--public_input_file") - .arg(&public_input_file) - .arg("--private_input_file") - .arg(&private_input_file) - .arg("--prover_config_file") - .arg(&config_file) - .arg("--parameter_file") - .arg(¶ms_file) - .arg("-generate_annotations") - .arg("--out_file") - .arg(&proof_path); - - let mut child_proof = command_proof.spawn()?; - let _status_proof = child_proof.wait()?; - - let result = fs::read_to_string(&proof_path).await?; - let proof: Value = serde_json::from_str(&result)?; - let final_result = serde_json::to_string_pretty(&proof)?; - - fs::remove_file(&program_input_path).await?; - fs::remove_file(&program_path).await?; - fs::remove_file(&proof_path).await?; - fs::remove_file(&trace_file).await?; - fs::remove_file(&memory_file).await?; - fs::remove_file(&public_input_file).await?; - fs::remove_file(&private_input_file).await?; - fs::remove_file(¶ms_file).await?; - - Ok(final_result) +) -> impl IntoResponse { + let thread_pool = app_state.thread_pool.clone(); + let job_store = app_state.job_store.clone(); + let job_id = create_job(&job_store).await; + let thread = thread_pool.lock().await; + thread + .execute( + job_id, + job_store, + path, + CairoVersionedInput::Cairo0(program_input), + app_state.sse_tx.clone(), + ) + .await + .into_response(); + let body = json!({ + "job_id": job_id + }); + (StatusCode::ACCEPTED, body.to_string()) } diff --git a/prover/src/prove/cairo1.rs b/prover/src/prove/cairo1.rs deleted file mode 100644 index 21f9ce8..0000000 --- a/prover/src/prove/cairo1.rs +++ /dev/null @@ -1,105 +0,0 @@ -use crate::auth::jwt::Claims; -use crate::prove::errors::ProveError; -use axum::Json; -use common::Cairo1ProverInput; -use config_generator::generate_config; -use serde_json::Value; -use tokio::fs; - -use std::path::{Path, PathBuf}; -use std::process::Command; - -pub async fn root( - _claims: Claims, - Json(program_input): Json, -) -> Result { - let program_input_path: PathBuf = Path::new("resources/cairo/input.txt").to_path_buf(); - let program_path: PathBuf = Path::new("resources/cairo/program.json").to_path_buf(); - let proof_path: PathBuf = Path::new("program_proof_cairo1.json").to_path_buf(); - let trace_file = Path::new("resources/cairo/program_trace.trace").to_path_buf(); - let memory_file = Path::new("resources/cairo/program_memory.memory").to_path_buf(); - let public_input_file = Path::new("resources/cairo/program_public_input.json").to_path_buf(); - let private_input_file = Path::new("resources/cairo/program_private_input.json").to_path_buf(); - let params_file = Path::new("resources/cairo/cpu_air_params.json").to_path_buf(); - let config_file = Path::new("config/cpu_air_prover_config.json").to_path_buf(); - - let input = serde_json::to_string(&program_input.program_input)?; - let program = serde_json::to_string(&program_input.program)?; - let layout = program_input.layout; - - let json_value: Value = serde_json::from_str(&input)?; - - if let Value::Array(array) = json_value { - let output_str = array - .into_iter() - .filter_map(|v| v.as_str().map(|s| s.to_owned())) - .collect::>() - .join(" "); - - fs::write(program_input_path.clone(), output_str).await?; - } else { - eprintln!("Expected a JSON array"); - std::process::exit(1); - } - - fs::write(&program_path, &program).await?; - - //run cairo1-run - let mut command = Command::new("cairo1-run"); - command - .arg("--trace_file") - .arg(&trace_file) - .arg("--memory_file") - .arg(&memory_file) - .arg("--layout") - .arg(layout) - .arg("--proof_mode") - .arg("--air_public_input") - .arg(&public_input_file) - .arg("--air_private_input") - .arg(&private_input_file) - .arg("--args_file") - .arg(&program_input_path) - .arg(&program_path); - - let mut child = command.spawn()?; - let _status = child.wait()?; - - generate_config::generate( - "resources/cairo/program_public_input.json", - "resources/cairo/cpu_air_params.json", - ); - - //run cpu_air_prover - let mut command_proof = Command::new("cpu_air_prover"); - command_proof - .arg("--out_file") - .arg(&proof_path) - .arg("--private_input_file") - .arg(&private_input_file) - .arg("--public_input_file") - .arg(&public_input_file) - .arg("--prover_config_file") - .arg(&config_file) - .arg("--parameter_file") - .arg(¶ms_file) - .arg("-generate-annotations"); - - let mut child_proof = command_proof.spawn()?; - let _status_proof = child_proof.wait()?; - - let result = fs::read_to_string(&proof_path).await?; - let proof: Value = serde_json::from_str(&result)?; - let final_result = serde_json::to_string_pretty(&proof)?; - - fs::remove_file(&program_input_path).await?; - fs::remove_file(&program_path).await?; - fs::remove_file(&proof_path).await?; - fs::remove_file(&trace_file).await?; - fs::remove_file(&memory_file).await?; - fs::remove_file(&public_input_file).await?; - fs::remove_file(&private_input_file).await?; - fs::remove_file(¶ms_file).await?; - - Ok(final_result) -} diff --git a/prover/src/prove/errors.rs b/prover/src/prove/errors.rs deleted file mode 100644 index 125ddde..0000000 --- a/prover/src/prove/errors.rs +++ /dev/null @@ -1,105 +0,0 @@ -use axum::{http::StatusCode, response::IntoResponse, Json}; -use serde_json::json; -use std::{env::VarError, net::AddrParseError}; -use thiserror::Error; - -use crate::auth::authorizer::AuthorizerError; - -#[derive(Debug, Error)] -pub enum ServerError { - #[error("server error")] - Server(#[from] std::io::Error), - - #[error("failed to parse address")] - AddressParse(#[from] AddrParseError), - - #[error("failed to initializer authorizer")] - AuthorizerCreation(#[from] AuthorizerError), -} - -#[derive(Error, Debug)] -pub enum ProveError { - #[error("Unauthorized public key request")] - UnauthorizedPublicKey, - - #[error("HexDecode Error")] - HexDecodeError(String), - - #[error("Failed to read env variable")] - EnvVarFailed(#[from] VarError), - - #[error("failed to parse result")] - Parse(#[from] serde_json::Error), - - #[error("unauthorized access")] - Unauthorized(ed25519_dalek::ed25519::Error), - - #[error("resource not found")] - NotFound(String), - - #[error("internal server error")] - InternalServerError(String), - - #[error("Missing or invalid public key")] - MissingPublicKey, - - #[error(transparent)] - Auth(#[from] AuthError), // Embedding AuthError within ProveError - - #[error("Failed to parse json")] - JsonParsingFailed(String), - - #[error("File read error")] - FileReadError(#[from] std::io::Error), - - #[error("Authorization failure")] - AuthorizationFailure(#[from] AuthorizerError), -} - -impl IntoResponse for ProveError { - fn into_response(self) -> axum::response::Response { - let (status, error_message) = match &self { - ProveError::Parse(_) => (StatusCode::BAD_REQUEST, self.to_string()), - ProveError::UnauthorizedPublicKey => (StatusCode::UNAUTHORIZED, self.to_string()), - ProveError::Unauthorized(_) => (StatusCode::UNAUTHORIZED, self.to_string()), - ProveError::NotFound(_) => (StatusCode::NOT_FOUND, self.to_string()), - ProveError::InternalServerError(_) => { - (StatusCode::INTERNAL_SERVER_ERROR, self.to_string()) - } - ProveError::MissingPublicKey => (StatusCode::BAD_REQUEST, self.to_string()), - ProveError::Auth(auth_error) => match auth_error { - AuthError::InvalidToken => (StatusCode::BAD_REQUEST, "Invalid token".to_string()), - AuthError::MissingAuthorizationHeader => ( - StatusCode::UNAUTHORIZED, - "Missing authorization header".to_string(), - ), - AuthError::Unauthorized => { - (StatusCode::UNAUTHORIZED, "Unauthorized access".to_string()) - } - }, - ProveError::FileReadError(_) => (StatusCode::INTERNAL_SERVER_ERROR, self.to_string()), - ProveError::JsonParsingFailed(_) => { - (StatusCode::INTERNAL_SERVER_ERROR, self.to_string()) - } - ProveError::EnvVarFailed(_) => (StatusCode::INTERNAL_SERVER_ERROR, self.to_string()), - ProveError::HexDecodeError(_) => (StatusCode::INTERNAL_SERVER_ERROR, self.to_string()), - ProveError::AuthorizationFailure(_) => { - (StatusCode::INTERNAL_SERVER_ERROR, self.to_string()) - } - }; - let body = Json(json!({ "error": error_message })); - (status, body).into_response() - } -} - -#[derive(Error, Debug)] -pub enum AuthError { - #[error("Invalid token")] - InvalidToken, - - #[error("Missing authorization header")] - MissingAuthorizationHeader, - - #[error("Unauthorized")] - Unauthorized, -} diff --git a/prover/src/prove/mod.rs b/prover/src/prove/mod.rs index e6c7612..883ac94 100644 --- a/prover/src/prove/mod.rs +++ b/prover/src/prove/mod.rs @@ -1,13 +1,12 @@ -use crate::server::AppState; use axum::{routing::post, Router}; + +use crate::server::AppState; +mod cairo; mod cairo0; -mod cairo1; -pub mod errors; -pub mod models; -pub fn router(app_state: &AppState) -> Router { +pub fn router(app_state: AppState) -> Router { Router::new() .route("/cairo0", post(cairo0::root)) - .route("/cairo1", post(cairo1::root)) - .with_state(app_state.clone()) + .route("/cairo", post(cairo::root)) + .with_state(app_state) } diff --git a/prover/src/server.rs b/prover/src/server.rs index 6afd152..c80a600 100644 --- a/prover/src/server.rs +++ b/prover/src/server.rs @@ -1,36 +1,44 @@ -use crate::{ - auth::{ - self, - authorizer::{Authorizer, FileAuthorizer}, - }, - prove, - verifier::verify_proof, - Args, +use crate::auth::auth; +use crate::auth::auth_errors::AuthorizerError; +use crate::auth::authorizer::{AuthorizationProvider, Authorizer, FileAuthorizer}; +use crate::errors::ProverError; +use crate::extractors::workdir::TempDirHandle; +use crate::sse::sse_handler; +use crate::threadpool::ThreadPool; +use crate::utils::job::{get_job, JobStore}; +use crate::utils::shutdown::shutdown_signal; +use crate::verifier::root; +use crate::{prove, Args}; +use axum::{ + middleware, + routing::{get, post}, + serve, Router, }; -use axum::{routing::post, Router}; -use prove::errors::ServerError; -use std::{ - collections::HashMap, - sync::{Arc, Mutex}, -}; -use std::{net::SocketAddr, time::Duration}; +use core::net::SocketAddr; +use ed25519_dalek::VerifyingKey; +use std::collections::HashMap; +use std::sync::Arc; use tokio::net::TcpListener; -use tower_http::{limit::RequestBodyLimitLayer, timeout::TimeoutLayer, trace::TraceLayer}; +use tokio::sync::broadcast::{self, Sender}; +use tokio::sync::Mutex; +use tracing::trace; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; -use utils::shutdown::shutdown_signal; -#[derive(Debug, Clone)] +type NonceString = String; +#[derive(Clone)] pub struct AppState { - pub prover_image_name: String, + pub job_store: JobStore, + pub thread_pool: Arc>, pub message_expiration_time: usize, pub session_expiration_time: usize, pub jwt_secret_key: String, - pub nonces: Arc>>, + pub nonces: Arc>>, pub authorizer: Authorizer, + pub admin_key: VerifyingKey, + pub sse_tx: Arc>>, } -pub async fn start(args: Args) -> Result<(), ServerError> { - // Enable tracing. +pub async fn start(args: Args) -> Result<(), ProverError> { tracing_subscriber::registry() .with( tracing_subscriber::EnvFilter::try_from_default_env() @@ -39,57 +47,52 @@ pub async fn start(args: Args) -> Result<(), ServerError> { .with(tracing_subscriber::fmt::layer()) .init(); - let keys = args.authorized_keys.clone().unwrap_or_default(); + let authorizer = + Authorizer::Persistent(FileAuthorizer::new(args.authorized_keys_path.clone()).await?); - let authorizer = match args.authorized_keys_path { - Some(path) => { - tracing::trace!("Using authorized keys file"); - Authorizer::Persistent(FileAuthorizer::new(path).await?) - } - None => { - let authorized_keys = args.authorized_keys.unwrap_or_default(); - tracing::trace!("Using memory authorization"); - Authorizer::Memory(authorized_keys.into()) - } - }; + let admin_key_bytes = prefix_hex::decode::>(args.admin_key) + .map_err(|e| AuthorizerError::PrefixHexConversionError(e.to_string()))?; + let admin_key = VerifyingKey::from_bytes(&admin_key_bytes.try_into().unwrap())?; - let state = AppState { - prover_image_name: "Sample".to_string(), - nonces: Arc::new(Mutex::new(HashMap::new())), - message_expiration_time: args.message_expiration_time as usize, - session_expiration_time: args.session_expiration_time as usize, + authorizer.authorize(admin_key).await?; + for key in args.authorized_keys.iter() { + let verifying_key_bytes = prefix_hex::decode::>(key) + .map_err(|e| AuthorizerError::PrefixHexConversionError(e.to_string()))?; + let verifying_key = VerifyingKey::from_bytes(&verifying_key_bytes.try_into().unwrap())?; + authorizer.authorize(verifying_key).await?; + } + let (sse_tx, _) = broadcast::channel(100); + let app_state = AppState { + message_expiration_time: args.message_expiration_time, + session_expiration_time: args.session_expiration_time, jwt_secret_key: args.jwt_secret_key, + nonces: Arc::new(Mutex::new(HashMap::new())), authorizer, + job_store: Arc::new(Mutex::new(Vec::new())), + thread_pool: Arc::new(Mutex::new(ThreadPool::new(args.num_workes))), + admin_key, + sse_tx: Arc::new(Mutex::new(sse_tx)), }; - async fn ok_handler() -> &'static str { - "OK" - } - - let ok_router = Router::new().route("/", axum::routing::get(ok_handler)); - - // Create a regular axum app. let app = Router::new() - .nest("/", ok_router) - .nest("/", auth::auth(&state)) - .nest("/prove", prove::router(&state)) - .route("/verify", post(verify_proof)) - .layer(( - RequestBodyLimitLayer::new(100 * 1024 * 1024), - TraceLayer::new_for_http(), - TimeoutLayer::new(Duration::from_secs(60 * 60)), - )); + .route("/verify", post(root)) + .route("/get-job/:id", get(get_job)) + .route("/sse", get(sse_handler)) + .with_state(app_state.clone()) + .nest("/", auth(app_state.clone())) + .nest("/prove", prove::router(app_state.clone())) + .layer(middleware::from_extractor::()); - let address: SocketAddr = format!("{}:{}", args.host, args.port).parse()?; - tracing::trace!("start listening on {}", address); - tracing::trace!("provided public keys {:?}", keys); + let address: SocketAddr = format!("{}:{}", args.host, args.port) + .parse() + .map_err(ProverError::AddressParse)?; - // Create a `TcpListener` using tokio. let listener = TcpListener::bind(address).await?; - // Run the server with graceful shutdown - axum::serve(listener, app) - .with_graceful_shutdown(shutdown_signal()) + trace!("Listening on {}", address); + + serve(listener, app) + .with_graceful_shutdown(shutdown_signal(app_state.thread_pool)) .await?; Ok(()) diff --git a/prover/src/sse.rs b/prover/src/sse.rs new file mode 100644 index 0000000..ffe46d7 --- /dev/null +++ b/prover/src/sse.rs @@ -0,0 +1,58 @@ +use crate::{auth::jwt::Claims, server::AppState}; +use async_stream::stream; +use axum::{ + extract::{Query, State}, + response::{sse::KeepAlive, Sse}, +}; +use common::models::JobStatus; +use futures::Stream; +use serde::{Deserialize, Serialize}; +use std::convert::Infallible; +use tracing::info; + +#[derive(Deserialize, Serialize)] +pub struct JobParams { + job_id: u64, +} +pub async fn sse_handler( + State(state): State, + Query(params): Query, + _claims: Claims, +) -> Sse>> { + info!("SSE handler connected"); + let mut rx = state.sse_tx.lock().await.subscribe(); + let job_id = params.job_id; + + let job_status = { + let jobs = state.job_store.lock().await; + jobs.iter() + .find(|job| job.id == job_id) + .map(|job| job.status.clone()) + }; + + let stream = stream! { + if job_status.is_some() && matches!(job_status.clone().unwrap(), JobStatus::Completed | JobStatus::Failed) { + yield Ok(axum::response::sse::Event::default().data(serde_json::to_string(&(job_status.unwrap(), job_id)).unwrap())); + return; + } + while let Ok(message) = rx.recv().await { + match serde_json::from_str::<(JobStatus, u64)>(&message) { + Ok((status, received_job_id)) => { + if job_id == received_job_id { + info!("Sending message: {}", message); + yield Ok(axum::response::sse::Event::default().data(message)); + // If the job is completed or failed, break the loop to stop sending events + if matches!(status, JobStatus::Completed | JobStatus::Failed) { + info!("Job {} completed or failed, stopping SSE.", received_job_id); + break; + } + } else { + info!("Ignoring message for job {} as it doesn't match requested job IDs ", received_job_id); + } + } + Err(e) => println!("Failed to deserialize job status: {}", e), + } + } + }; + Sse::new(stream).keep_alive(KeepAlive::default()) +} diff --git a/prover/src/threadpool/mod.rs b/prover/src/threadpool/mod.rs new file mode 100644 index 0000000..3eaca9f --- /dev/null +++ b/prover/src/threadpool/mod.rs @@ -0,0 +1,131 @@ +use crate::{errors::ProverError, threadpool::prove::prove, utils::job::JobStore}; +use common::{cairo0_prover_input::Cairo0ProverInput, cairo_prover_input::CairoProverInput}; +use std::sync::Arc; +use tempfile::TempDir; +use tokio::{ + spawn, + sync::{broadcast::Sender, mpsc, Mutex}, + task::JoinHandle, +}; +use tracing::trace; +pub mod prove; +type ReceiverType = Arc< + Mutex< + mpsc::Receiver<( + u64, + JobStore, + TempDir, + CairoVersionedInput, + Arc>>, + )>, + >, +>; +type SenderType = Option< + mpsc::Sender<( + u64, + JobStore, + TempDir, + CairoVersionedInput, + Arc>>, + )>, +>; +pub struct ThreadPool { + workers: Vec, + sender: SenderType, +} +pub enum CairoVersionedInput { + Cairo(CairoProverInput), + Cairo0(Cairo0ProverInput), +} + +impl ThreadPool { + pub fn new(size: usize) -> ThreadPool { + assert!(size > 0); + + let (sender, receiver) = mpsc::channel(100); + + let receiver = Arc::new(Mutex::new(receiver)); + + let mut workers = Vec::with_capacity(size); + + for id in 0..size { + workers.push(Worker::new(id, Arc::clone(&receiver))); + } + + ThreadPool { + workers, + sender: Some(sender), + } + } + + pub async fn execute( + &self, + job_id: u64, + job_store: JobStore, + dir: TempDir, + program_input: CairoVersionedInput, + sse_tx: Arc>>, + ) -> Result<(), ProverError> { + self.sender + .as_ref() + .ok_or(ProverError::CustomError( + "Thread pool is shutdown".to_string(), + ))? + .send((job_id, job_store, dir, program_input, sse_tx)) + .await?; + Ok(()) + } + + pub async fn shutdown(&mut self) -> Result<(), ProverError> { + if let Some(sender) = self.sender.take() { + drop(sender); // Dropping the sender signals that no more messages will be sent + } + + // Wait for each worker to finish its current task + for worker in &mut self.workers { + if let Some(handle) = worker.thread.take() { + if let Err(e) = handle.await { + eprintln!("Error waiting for worker: {:?}", e); + return Err(ProverError::CustomError(format!("Worker error: {:?}", e))); + } + } + } + + Ok(()) + } +} + +struct Worker { + _id: usize, + thread: Option>, +} + +impl Worker { + fn new(id: usize, receiver: ReceiverType) -> Worker { + let thread = spawn(async move { + loop { + let message = receiver.lock().await.recv().await; + match message { + Some((job_id, job_store, dir, program_input, sse_tx)) => { + trace!("Worker {id} got a job; executing."); + + if let Err(e) = prove(job_id, job_store, dir, program_input, sse_tx).await { + eprintln!("Worker {id} encountered an error: {:?}", e); + } + + trace!("Worker {id} finished the job."); + } + None => { + trace!("Worker {id} detected shutdown signal."); + break; + } + } + } + }); + + Worker { + _id: id, + thread: Some(thread), + } + } +} diff --git a/prover/src/threadpool/prove.rs b/prover/src/threadpool/prove.rs new file mode 100644 index 0000000..21516da --- /dev/null +++ b/prover/src/threadpool/prove.rs @@ -0,0 +1,194 @@ +use super::CairoVersionedInput; +use crate::errors::ProverError; +use crate::utils::{ + config::generate, + job::{update_job_status, JobStore}, +}; +use common::models::JobStatus; +use serde_json::Value; +use starknet_types_core::felt::Felt; +use std::fs; +use std::path::PathBuf; +use std::str::FromStr; +use std::sync::Arc; +use tempfile::TempDir; +use tokio::process::Command; +use tokio::sync::broadcast::Sender; +use tokio::sync::Mutex; +use tracing::trace; + +pub async fn prove( + job_id: u64, + job_store: JobStore, + dir: TempDir, + program_input: CairoVersionedInput, + sse_tx: Arc>>, +) -> Result<(), ProverError> { + update_job_status(job_id, &job_store, JobStatus::Running, None).await; + let path = dir.into_path(); + let program_input_path: PathBuf = path.join("program_input.json"); + let program_path: PathBuf = path.join("program.json"); + let proof_path: PathBuf = path.join("program_proof_cairo.json"); + let trace_file = path.join("program_trace.trace"); + let memory_file = path.join("program_memory.memory"); + let public_input_file = path.join("program_public_input.json"); + let private_input_file = path.join("program_private_input.json"); + let params_file = path.join("cpu_air_params.json"); + let config_file = PathBuf::from_str("config/cpu_air_prover_config.json")?; + match program_input { + CairoVersionedInput::Cairo(input) => { + let program = serde_json::to_string(&input.program)?; + let layout = input.layout; + let input = prepare_input(input.program_input)?; + fs::write(&program_path, &program)?; + fs::write(&program_input_path, &input)?; + cairo_run( + trace_file, + memory_file, + layout, + public_input_file.clone(), + private_input_file.clone(), + program_input_path, + program_path, + ) + .await?; + } + CairoVersionedInput::Cairo0(input) => { + fs::write( + program_input_path.clone(), + serde_json::to_string(&input.program_input)?, + )?; + fs::write(&program_path, serde_json::to_string(&input.program)?)?; + let layout = input.layout; + cairo0_run( + trace_file, + memory_file, + layout, + public_input_file.clone(), + private_input_file.clone(), + program_input_path, + program_path, + ) + .await?; + } + } + + generate(public_input_file.clone(), params_file.clone()); + + let mut command_proof = Command::new("cpu_air_prover"); + command_proof + .arg("--out_file") + .arg(&proof_path) + .arg("--private_input_file") + .arg(&private_input_file) + .arg("--public_input_file") + .arg(&public_input_file) + .arg("--prover_config_file") + .arg(&config_file) + .arg("--parameter_file") + .arg(¶ms_file) + .arg("-generate-annotations"); + + let mut child_proof = command_proof.spawn()?; + let status_proof = child_proof.wait().await?; + let result = fs::read_to_string(&proof_path)?; + let proof: Value = serde_json::from_str(&result)?; + let final_result = serde_json::to_string_pretty(&proof)?; + let sender = sse_tx.lock().await; + + if status_proof.success() { + update_job_status(job_id, &job_store, JobStatus::Completed, Some(final_result)).await; + if sender.receiver_count() > 0 { + sender + .send(serde_json::to_string(&(JobStatus::Completed, job_id))?) + .unwrap(); + } + } else { + update_job_status(job_id, &job_store, JobStatus::Failed, Some(final_result)).await; + if sender.receiver_count() > 0 { + sender + .send(serde_json::to_string(&(JobStatus::Failed, job_id))?) + .unwrap(); + } + } + Ok(()) +} + +pub async fn cairo0_run( + trace_file: PathBuf, + memory_file: PathBuf, + layout: String, + public_input_file: PathBuf, + private_input_file: PathBuf, + program_input_path: PathBuf, + program_path: PathBuf, +) -> Result<(), ProverError> { + trace!("Running cairo0-run"); + let mut command = Command::new("cairo-run"); + command + .arg("--trace_file") + .arg(&trace_file) + .arg("--memory_file") + .arg(&memory_file) + .arg("--layout") + .arg(layout) + .arg("--proof_mode") + .arg("--air_public_input") + .arg(&public_input_file) + .arg("--air_private_input") + .arg(&private_input_file) + .arg("--program_input") + .arg(&program_input_path) + .arg("--program") + .arg(&program_path); + + let mut child = command.spawn()?; + let _status = child.wait().await?; + Ok(()) +} +pub async fn cairo_run( + trace_file: PathBuf, + memory_file: PathBuf, + layout: String, + public_input_file: PathBuf, + private_input_file: PathBuf, + program_input_path: PathBuf, + program_path: PathBuf, +) -> Result<(), ProverError> { + let mut command = Command::new("cairo1-run"); + command + .arg("--trace_file") + .arg(&trace_file) + .arg("--memory_file") + .arg(&memory_file) + .arg("--layout") + .arg(layout) + .arg("--proof_mode") + .arg("--air_public_input") + .arg(&public_input_file) + .arg("--air_private_input") + .arg(&private_input_file) + .arg("--args_file") + .arg(&program_input_path) + .arg(&program_path); + + let mut child = command.spawn()?; + let _status = child.wait().await?; + Ok(()) +} +pub fn prepare_input(felts: Vec) -> Result { + if felts.is_empty() { + return Err(ProverError::CustomError( + "Input is empty, input must be a array of felt in format [felt,...,felt]".to_string(), + )); + } + let mut input = String::from("["); + for i in 0..felts.len() { + input.push_str(&felts[i].to_string()); + if i != felts.len() - 1 { + input.push(' '); + } + } + input.push(']'); + Ok(input) +} diff --git a/prover/src/utils/config.rs b/prover/src/utils/config.rs new file mode 100644 index 0000000..28359b3 --- /dev/null +++ b/prover/src/utils/config.rs @@ -0,0 +1,108 @@ +use serde::{Deserialize, Serialize}; +use serde_json::Value; +use std::fs::File; +use std::io::{Read, Write}; +use std::path::PathBuf; +use std::process; + +#[derive(Serialize, Deserialize, Debug)] +struct StarkFri { + fri_step_list: Vec, + last_layer_degree_bound: u32, + n_queries: u32, + proof_of_work_bits: u32, +} + +#[derive(Serialize, Deserialize, Debug)] +struct Stark { + fri: StarkFri, + log_n_cosets: u32, +} + +#[derive(Serialize, Deserialize, Debug)] +struct Template { + field: String, + channel_hash: String, + commitment_hash: String, + n_verifier_friendly_commitment_layers: u32, + pow_hash: String, + statement: Value, + stark: Stark, + use_extension_field: bool, + verifier_friendly_channel_updates: bool, + verifier_friendly_commitment_hash: String, +} + +fn calculate_fri_step_list(n_steps: u32, degree_bound: u32) -> Vec { + let fri_degree = ((n_steps as f64 / degree_bound as f64).log(2.0).round() as u32) + 4; + let mut steps = vec![0]; + steps.extend(vec![4; (fri_degree / 4) as usize]); + if fri_degree % 4 != 0 { + steps.push(fri_degree % 4); + } + steps +} + +fn update_template_and_save_to_file( + template: &mut Template, + fri_step_list: Vec, + file_path: PathBuf, +) -> Result<(), String> { + template.stark.fri.fri_step_list = fri_step_list; + let mut file: File = File::create(file_path).map_err(|e| e.to_string())?; + let json_string = serde_json::to_string_pretty(template).expect("Failed to serialize JSON"); + file.write_all(json_string.as_bytes()) + .map_err(|e| e.to_string()) +} + +fn read_json_from_file(file_path: PathBuf) -> Result { + let mut buffer = String::new(); + let mut file = File::open(file_path).map_err(|e| e.to_string())?; + file.read_to_string(&mut buffer) + .map_err(|e| e.to_string())?; + serde_json::from_str(&buffer).map_err(|e| e.to_string()) +} + +pub fn generate(input_file: PathBuf, output_file: PathBuf) { + let program_public_input: Value = match read_json_from_file(input_file) { + Ok(data) => data, + Err(err) => { + eprintln!("Error: Invalid JSON input. {}", err); + process::exit(1); + } + }; + + let n_steps = match program_public_input["n_steps"].as_u64() { + Some(val) => val as u32, + None => { + eprintln!("Error: 'n_steps' is missing or not an integer."); + process::exit(1); + } + }; + + let mut template = Template { + field: "PrimeField0".to_string(), + channel_hash: "poseidon3".to_string(), + commitment_hash: "blake256_masked160_lsb".to_string(), + n_verifier_friendly_commitment_layers: 9999, + pow_hash: "keccak256".to_string(), + statement: serde_json::json!({ "page_hash": "pedersen" }), + stark: Stark { + fri: StarkFri { + fri_step_list: vec![0, 4, 4, 4], + last_layer_degree_bound: 128, + n_queries: 16, + proof_of_work_bits: 30, + }, + log_n_cosets: 3, + }, + use_extension_field: false, + verifier_friendly_channel_updates: true, + verifier_friendly_commitment_hash: "poseidon3".to_string(), + }; + + let last_layer_degree_bound = template.stark.fri.last_layer_degree_bound; + + let fri_step_list = calculate_fri_step_list(n_steps, last_layer_degree_bound); + let _ = update_template_and_save_to_file(&mut template, fri_step_list, output_file); +} diff --git a/prover/src/utils/job.rs b/prover/src/utils/job.rs new file mode 100644 index 0000000..54cfa5a --- /dev/null +++ b/prover/src/utils/job.rs @@ -0,0 +1,100 @@ +use axum::{ + extract::{Path, State}, + http::StatusCode, + response::IntoResponse, + Json, +}; +use common::models::JobStatus; +use serde::Serialize; +use std::sync::Arc; +use tokio::sync::Mutex; + +use crate::{auth::jwt::Claims, server::AppState}; + +#[derive(Serialize, Clone)] +pub struct Job { + pub id: u64, + pub status: JobStatus, + pub result: Option, // You can change this to any type based on your use case +} + +#[derive(Serialize)] +#[serde(untagged)] +pub enum JobResponse { + InProgress { id: u64, status: JobStatus }, + Completed { result: String, status: JobStatus }, + Failed { error: String }, +} +pub type JobStore = Arc>>; + +pub async fn create_job(job_store: &JobStore) -> u64 { + let mut jobs = job_store.lock().await; + let job_id = jobs.len() as u64; + let new_job = Job { + id: job_id, + status: JobStatus::Pending, + result: None, + }; + jobs.push(new_job); + drop(jobs); + job_id +} + +pub async fn update_job_status( + job_id: u64, + job_store: &JobStore, + status: JobStatus, + result: Option, +) { + let mut jobs = job_store.lock().await; + if let Some(job) = jobs.iter_mut().find(|job| job.id == job_id) { + job.status = status; + job.result = result; + } + drop(jobs); +} +pub async fn get_job( + Path(id): Path, + State(app_state): State, + _claims: Claims, +) -> impl IntoResponse { + let job_store = &app_state.job_store; + let jobs = job_store.lock().await; + if let Some(job) = jobs.iter().find(|job| job.id == id) { + let (status, response) = match job.status { + JobStatus::Pending | JobStatus::Running => ( + StatusCode::OK, + Json(JobResponse::InProgress { + id: job.id, + status: job.status.clone(), + }), + ), + JobStatus::Completed => ( + StatusCode::OK, + Json(JobResponse::Completed { + status: job.status.clone(), + result: job + .result + .clone() + .unwrap_or_else(|| "No result available".to_string()), + }), + ), + JobStatus::Failed => ( + StatusCode::INTERNAL_SERVER_ERROR, + Json(JobResponse::Failed { + error: job + .result + .clone() + .unwrap_or_else(|| "Unknown error".to_string()), + }), + ), + }; + (status, response).into_response() + } else { + ( + StatusCode::NOT_FOUND, + Json(format!("Job with id {} not found", id)), + ) + .into_response() + } +} diff --git a/prover/src/utils/mod.rs b/prover/src/utils/mod.rs new file mode 100644 index 0000000..e484f01 --- /dev/null +++ b/prover/src/utils/mod.rs @@ -0,0 +1,3 @@ +pub mod config; +pub mod job; +pub mod shutdown; diff --git a/prover/src/utils/shutdown.rs b/prover/src/utils/shutdown.rs new file mode 100644 index 0000000..86ca829 --- /dev/null +++ b/prover/src/utils/shutdown.rs @@ -0,0 +1,42 @@ +use crate::threadpool::ThreadPool; +use std::sync::Arc; +use tokio::signal; +use tokio::sync::Mutex; +use tracing::info; // Import the logging macro + +pub async fn shutdown_signal(thread_pool: Arc>) { + let ctrl_c = async { + signal::ctrl_c() + .await + .expect("failed to install Ctrl+C handler"); + }; + + #[cfg(unix)] + let terminate = async { + signal::unix::signal(signal::unix::SignalKind::terminate()) + .expect("failed to install signal handler") + .recv() + .await; + }; + + #[cfg(not(unix))] + let terminate = std::future::pending::<()>(); + + tokio::select! { + _ = ctrl_c => { + info!("Shutting down the server"); + }, + _ = terminate => { + info!("Shutting down the server due to termination signal"); + }, + } + + // Trigger thread pool shutdown + info!("Shutting down the thread pool..."); + let mut thread_pool = thread_pool.lock().await; + if let Err(e) = thread_pool.shutdown().await { + eprintln!("Error during thread pool shutdown: {:?}", e); + } else { + info!("Thread pool shutdown completed successfully."); + } +} diff --git a/prover/src/verifier.rs b/prover/src/verifier.rs index 91bf16d..49d1e6d 100644 --- a/prover/src/verifier.rs +++ b/prover/src/verifier.rs @@ -1,35 +1,80 @@ -use std::{path::PathBuf, process::Command}; +use crate::{ + auth::jwt::Claims, + errors::ProverError, + extractors::workdir::TempDirHandle, + server::AppState, + utils::job::{create_job, update_job_status, JobStore}, +}; +use axum::{extract::State, http::StatusCode, response::IntoResponse, Json}; +use common::models::JobStatus; +use serde_json::json; +use std::{process::Command, sync::Arc}; +use tempfile::TempDir; +use tokio::sync::broadcast::Sender; +use tokio::sync::Mutex; -use axum::Json; +pub async fn root( + State(app_state): State, + TempDirHandle(dir): TempDirHandle, + _claims: Claims, + Json(proof): Json, +) -> impl IntoResponse { + let job_id = create_job(&app_state.job_store).await; + let job_store = app_state.job_store.clone(); + tokio::spawn({ + async move { + if let Err(e) = + verify_proof(job_id, job_store.clone(), dir, proof, app_state.sse_tx).await + { + update_job_status(job_id, &job_store, JobStatus::Failed, Some(e.to_string())).await; + } + } + }); + + let body = json!({ + "job_id": job_id + }); + (StatusCode::ACCEPTED, body.to_string()) +} + +pub async fn verify_proof( + job_id: u64, + job_store: JobStore, + dir: TempDir, + proof: String, + sender: Arc>>, +) -> Result<(), ProverError> { + update_job_status(job_id, &job_store, JobStatus::Running, None).await; -pub async fn verify_proof(Json(proof): Json) -> Json { // Define the path for the proof file - let file = PathBuf::from("proof"); + let path = dir.into_path(); + let file = path.join("proof"); // Write the proof string to the file - if let Err(e) = std::fs::write(&file, proof) { - eprintln!("Failed to write proof to file: {}", e); - return Json(false); - } + std::fs::write(&file, &proof)?; // Create the command to run the verifier let mut command = Command::new("cpu_air_verifier"); command.arg("--in_file").arg(&file); // Execute the command and capture the status - let status = command.status(); - + let status = command.status()?; // Remove the proof file - if let Err(e) = std::fs::remove_file(&file) { - eprintln!("Failed to remove proof file: {}", e); - } - + std::fs::remove_file(&file)?; // Check if the command was successful - match status { - Ok(exit_status) => Json(exit_status.success()), - Err(e) => { - eprintln!("Failed to execute verifier: {}", e); - Json(false) - } + + update_job_status( + job_id, + &job_store, + JobStatus::Completed, + Some(status.success().to_string()), + ) + .await; + let sender = sender.lock().await; + if sender.receiver_count() > 0 { + sender + .send(serde_json::to_string(&(JobStatus::Completed, job_id))?) + .unwrap(); } + Ok(()) } diff --git a/rust-toolchain.toml b/rust-toolchain.toml index d2bc0cc..7ae2b72 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "1.78.0" +channel = "1.79.0" profile = "default" diff --git a/scripts/0-venv.sh b/scripts/0-venv.sh deleted file mode 100755 index 575f59c..0000000 --- a/scripts/0-venv.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env bash - -set -eux - -# Define the name of the virtual environment -VENV_NAME=".venv" - -# Check if the virtual environment already exists -if [ ! -d "$VENV_NAME" ]; then - # If it doesn't exist, create the virtual environment - python -m venv $VENV_NAME - - # Activate the virtual environment - . $VENV_NAME/bin/activate - - # Upgrade pip to the latest version - pip install --upgrade pip - - # Install the required packages from the requirements.txt file - pip install sympy==1.12.1 - pip install cairo-lang==0.13.1 - - # Deactivate the virtual environment - deactivate -else - # If it does exist, print a message indicating that it already exists - echo "Virtual environment $VENV_NAME already exists." -fi diff --git a/scripts/1-compile.sh b/scripts/1-compile.sh deleted file mode 100644 index ea88ddb..0000000 --- a/scripts/1-compile.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash - -set -eux - -. .venv/bin/activate - -mkdir -p resources - -cairo-compile \ - examples/CairoZero/fibonacci.cairo \ - --output resources/fibonacci_compiled.json \ - --proof_mode - -deactivate diff --git a/scripts/2-merge.sh b/scripts/2-merge.sh deleted file mode 100644 index ae3672f..0000000 --- a/scripts/2-merge.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -set -eux - -# This script assumes Python is installed and accessible from the command line as 'python' - -# Variables for JSON files and output -FILE1="resources/fibonacci_compiled.json" -FILE2="examples/CairoZero/input.json" -OUTPUT="examples/CairoZero/prover_input.json" -LAYOUT='recursive' - -# Call the Python script to combine the JSON files -python scripts/combine_json.py "$FILE1" "$FILE2" "$LAYOUT" "$OUTPUT" - -cp "$OUTPUT" examples/Cairo/prover_input.json diff --git a/scripts/combine_json.py b/scripts/combine_json.py deleted file mode 100644 index ecabbd6..0000000 --- a/scripts/combine_json.py +++ /dev/null @@ -1,21 +0,0 @@ -import json - -def combine_json_files(file1, file2, layout, output_file): - with open(file1, 'r') as f: - data1 = json.load(f) - - with open(file2, 'r') as f: - data2 = json.load(f) - - combined_data = { - "program_input": data2, - "layout": layout, - "program": data1 - } - - with open(output_file, 'w') as f: - json.dump(combined_data, f, indent=4) - -if __name__ == "__main__": - import sys - combine_json_files(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4]) diff --git a/scripts/corelib_install.sh b/scripts/corelib_install.sh deleted file mode 100755 index aee0216..0000000 --- a/scripts/corelib_install.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -git clone --depth=1 -b v2.7.0-rc.3 https://github.com/starkware-libs/cairo.git \ - && mv cairo/corelib/ . \ - && rm -rf cairo/ \ No newline at end of file diff --git a/scripts/e2e_test.sh b/scripts/e2e_test.sh index 5ba97cc..5cebd9f 100755 --- a/scripts/e2e_test.sh +++ b/scripts/e2e_test.sh @@ -1,10 +1,9 @@ -#!/usr/bin/env bash +# !/usr/bin/env bash set -eux - -IMAGE_NAME="http_prover_test" - +IMAGE_NAME="http-prover-test" # Check if the image already exists +podman build -t $IMAGE_NAME . if podman images | grep -q "$IMAGE_NAME"; then echo "Image $IMAGE_NAME already exists. Skipping build step." else @@ -16,17 +15,24 @@ else fi fi +KEYGEN_OUTPUT=$(cargo run -p keygen) + +PUBLIC_KEY=$(echo "$KEYGEN_OUTPUT" | grep "Public key" | awk '{print $3}' | tr -d ',' | tr -d '[:space:]') +PRIVATE_KEY=$(echo "$KEYGEN_OUTPUT" | grep "Private key" | awk '{print $3}' | tr -d ',' | tr -d '[:space:]') + +KEYGEN_OUTPUT=$(cargo run -p keygen) + +ADMIN_PUBLIC_KEY=$(echo "$KEYGEN_OUTPUT" | grep "Public key" | awk '{print $3}' | tr -d ',' | tr -d '[:space:]') +ADMIN_PRIVATE_KEY=$(echo "$KEYGEN_OUTPUT" | grep "Private key" | awk '{print $3}' | tr -d ',' | tr -d '[:space:]') + podman run -d --replace --name http_prover_test \ - -p 3040:3000 localhost/http_prover_test \ - --jwt-secret-key "jwt" \ + -p 3040:3000 $IMAGE_NAME \ + --jwt-secret-key "secret" \ --message-expiration-time 3600 \ --session-expiration-time 3600 \ - --authorized-keys 0xed126082726a1062ed6e886b2d7aba42e4f8964a13b4569988bd4c50b9a62076 -if [ $? -ne 0 ]; then - echo "Failed to run the image. Exiting." - exit 1 -fi + --authorized-keys $PUBLIC_KEY,$ADMIN_PUBLIC_KEY \ + --admin-key $ADMIN_PUBLIC_KEY -cargo test --no-fail-fast --workspace --verbose -- --test-threads=1 +PRIVATE_KEY=$PRIVATE_KEY PROVER_URL="http://localhost:3040" ADMIN_PRIVATE_KEY=$ADMIN_PRIVATE_KEY cargo test --no-fail-fast --workspace --verbose -podman stop $IMAGE_NAME +podman stop http_prover_test \ No newline at end of file