From b2e4e414f09a1200fc7b443caf9c72ac769e32f2 Mon Sep 17 00:00:00 2001 From: dante <45801863+alexander-camuto@users.noreply.github.com> Date: Thu, 5 Dec 2024 10:35:06 -0500 Subject: [PATCH 1/2] chore: update pyo3 and add stub (#879) --- .cargo/config.toml | 13 + .github/workflows/rust.yml | 2 + .gitignore | 3 +- Cargo.lock | 264 ++++-- Cargo.toml | 13 +- examples/notebooks/felt_conversion_test.ipynb | 130 +++ ezkl.pyi | 851 ++++++++++++++++++ src/bin/py_stub_gen.rs | 9 + src/bindings/python.rs | 187 +++- src/bindings/wasm.rs | 9 +- src/circuit/ops/chip.rs | 14 +- src/circuit/ops/errors.rs | 3 + src/circuit/ops/mod.rs | 23 +- src/circuit/ops/region.rs | 5 +- src/commands.rs | 122 ++- src/graph/input.rs | 3 +- src/graph/mod.rs | 26 +- src/graph/vars.rs | 9 +- src/pfsys/mod.rs | 19 +- tests/py_integration_tests.rs | 11 + 20 files changed, 1504 insertions(+), 212 deletions(-) create mode 100644 examples/notebooks/felt_conversion_test.ipynb create mode 100644 ezkl.pyi create mode 100644 src/bin/py_stub_gen.rs diff --git a/.cargo/config.toml b/.cargo/config.toml index f7b4d5d54..16593afa3 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -2,3 +2,16 @@ runner = 'wasm-bindgen-test-runner' rustflags = ["-C", "target-feature=+atomics,+bulk-memory,+mutable-globals","-C", "link-arg=--max-memory=4294967296"] + + +[target.x86_64-apple-darwin] +rustflags = [ + "-C", "link-arg=-undefined", + "-C", "link-arg=dynamic_lookup", +] + +[target.aarch64-apple-darwin] +rustflags = [ + "-C", "link-arg=-undefined", + "-C", "link-arg=dynamic_lookup", +] \ No newline at end of file diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index eda30e81d..6132dd1a9 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -650,6 +650,8 @@ jobs: run: python -m venv .env --clear; source .env/bin/activate; pip install -r requirements.txt; python -m ensurepip --upgrade - name: Build python ezkl run: source .env/bin/activate; unset CONDA_PREFIX; maturin develop --features python-bindings --release + - name: Postgres tutorials + run: source .env/bin/activate; cargo nextest run py_tests::tests::felt_conversion_test_ --no-capture - name: Postgres tutorials run: source .env/bin/activate; cargo nextest run py_tests::tests::postgres_ --no-capture - name: Tictactoe tutorials diff --git a/.gitignore b/.gitignore index f0117a065..d072f0b1f 100644 --- a/.gitignore +++ b/.gitignore @@ -27,7 +27,6 @@ __pycache__/ *.pyc *.pyo *.py[cod] -bin/ build/ develop-eggs/ dist/ @@ -49,4 +48,4 @@ timingData.json !tests/assets/pk.key !tests/assets/vk.key docs/python/build -!tests/assets/vk_aggr.key \ No newline at end of file +!tests/assets/vk_aggr.key diff --git a/Cargo.lock b/Cargo.lock index c61efa7e9..33402da6d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -134,7 +134,7 @@ dependencies = [ "itoa", "serde", "serde_json", - "winnow 0.6.5", + "winnow 0.6.20", ] [[package]] @@ -308,7 +308,7 @@ checksum = "1a047897373be4bbb0224c1afdabca92648dc57a9c9ef6e7b0be3aff7a859c83" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.90", ] [[package]] @@ -410,7 +410,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.90", ] [[package]] @@ -427,7 +427,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.90", "syn-solidity", "tiny-keccak", ] @@ -445,7 +445,7 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.53", + "syn 2.0.90", "syn-solidity", ] @@ -456,7 +456,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cbcba3ca07cf7975f15d871b721fb18031eec8bce51103907f6dcce00b255d98" dependencies = [ "serde", - "winnow 0.6.5", + "winnow 0.6.20", ] [[package]] @@ -594,9 +594,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.81" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" +checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" [[package]] name = "anymap" @@ -873,7 +873,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.53", + "syn 2.0.90", ] [[package]] @@ -910,7 +910,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.90", ] [[package]] @@ -921,7 +921,7 @@ checksum = "461abc97219de0eaaf81fe3ef974a540158f3d079c2ab200f891f1a2ef201e85" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.90", ] [[package]] @@ -932,7 +932,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.90", ] [[package]] @@ -1299,7 +1299,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.90", ] [[package]] @@ -1622,7 +1622,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.90", ] [[package]] @@ -1709,7 +1709,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.90", ] [[package]] @@ -1817,7 +1817,7 @@ checksum = "6fd000fd6988e73bbe993ea3db9b1aa64906ab88766d654973924340c8cddb42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.90", ] [[package]] @@ -1933,8 +1933,9 @@ dependencies = [ "pg_bigdecimal", "portable-atomic", "pyo3", - "pyo3-asyncio", + "pyo3-async-runtimes", "pyo3-log", + "pyo3-stub-gen", "rand 0.8.5", "regex", "reqwest", @@ -2089,7 +2090,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.90", ] [[package]] @@ -2234,7 +2235,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.90", ] [[package]] @@ -2876,6 +2877,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "inventory" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f958d3d68f4167080a18141e10381e7634563984a537f2a49a30fd8e53ac5767" + [[package]] name = "ipnet" version = "2.9.0" @@ -2920,6 +2927,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.10" @@ -3103,7 +3119,7 @@ checksum = "fc2fb41a9bb4257a3803154bdf7e2df7d45197d1941c9b1a90ad815231630721" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.90", ] [[package]] @@ -3139,9 +3155,9 @@ checksum = "9374ef4228402d4b7e403e5838cb880d9ee663314b0a900d5a6aabf0c213552e" [[package]] name = "log" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "lru" @@ -3385,9 +3401,9 @@ dependencies = [ [[package]] name = "num-complex" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" dependencies = [ "num-traits", ] @@ -3456,6 +3472,21 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" +[[package]] +name = "numpy" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b94caae805f998a07d33af06e6a3891e38556051b8045c615470a71590e13e78" +dependencies = [ + "libc", + "ndarray", + "num-complex", + "num-integer", + "num-traits", + "pyo3", + "rustc-hash", +] + [[package]] name = "objc" version = "0.2.7" @@ -3515,7 +3546,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.90", ] [[package]] @@ -3689,7 +3720,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.90", ] [[package]] @@ -3756,7 +3787,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.90", ] [[package]] @@ -3794,7 +3825,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.90", ] [[package]] @@ -3972,7 +4003,7 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" dependencies = [ - "toml_edit", + "toml_edit 0.20.7", ] [[package]] @@ -4001,9 +4032,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.79" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] @@ -4053,15 +4084,15 @@ dependencies = [ [[package]] name = "pyo3" -version = "0.21.2" +version = "0.23.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e00b96a521718e08e03b1a622f01c8a8deb50719335de3f60b3b3950f069d8" +checksum = "e484fd2c8b4cb67ab05a318f1fd6fa8f199fcc30819f08f07d200809dba26c15" dependencies = [ "cfg-if", "indoc", "libc", "memoffset", - "parking_lot", + "once_cell", "portable-atomic", "pyo3-build-config", "pyo3-ffi", @@ -4070,33 +4101,33 @@ dependencies = [ ] [[package]] -name = "pyo3-asyncio" -version = "0.21.0" -source = "git+https://github.com/jopemachine/pyo3-asyncio/?branch=migration-pyo3-0.21#d1ec64076dd1b5c797db4b7b811f588466956d20" +name = "pyo3-async-runtimes" +version = "0.23.0" +source = "git+https://github.com/PyO3/pyo3-async-runtimes#c2b8441b4910b0b5100536b23c7a2fd43f9eacd0" dependencies = [ "futures", "once_cell", "pin-project-lite", "pyo3", - "pyo3-asyncio-macros", + "pyo3-async-runtimes-macros", "tokio", ] [[package]] -name = "pyo3-asyncio-macros" -version = "0.21.0" -source = "git+https://github.com/jopemachine/pyo3-asyncio/?branch=migration-pyo3-0.21#d1ec64076dd1b5c797db4b7b811f588466956d20" +name = "pyo3-async-runtimes-macros" +version = "0.23.0" +source = "git+https://github.com/PyO3/pyo3-async-runtimes#c2b8441b4910b0b5100536b23c7a2fd43f9eacd0" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.90", ] [[package]] name = "pyo3-build-config" -version = "0.21.2" +version = "0.23.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7883df5835fafdad87c0d888b266c8ec0f4c9ca48a5bed6bbb592e8dedee1b50" +checksum = "dc0e0469a84f208e20044b98965e1561028180219e35352a2afaf2b942beff3b" dependencies = [ "once_cell", "target-lexicon", @@ -4104,9 +4135,9 @@ dependencies = [ [[package]] name = "pyo3-ffi" -version = "0.21.2" +version = "0.23.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01be5843dc60b916ab4dad1dca6d20b9b4e6ddc8e15f50c47fe6d85f1fb97403" +checksum = "eb1547a7f9966f6f1a0f0227564a9945fe36b90da5a93b3933fc3dc03fae372d" dependencies = [ "libc", "pyo3-build-config", @@ -4114,9 +4145,9 @@ dependencies = [ [[package]] name = "pyo3-log" -version = "0.10.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2af49834b8d2ecd555177e63b273b708dea75150abc6f5341d0a6e1a9623976c" +checksum = "3eb421dc86d38d08e04b927b02424db480be71b777fa3a56f32e2f2a3a1a3b08" dependencies = [ "arc-swap", "log", @@ -4125,27 +4156,57 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.21.2" +version = "0.23.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77b34069fc0682e11b31dbd10321cbf94808394c56fd996796ce45217dfac53c" +checksum = "fdb6da8ec6fa5cedd1626c886fc8749bdcbb09424a86461eb8cdf096b7c33257" dependencies = [ "proc-macro2", "pyo3-macros-backend", "quote", - "syn 2.0.53", + "syn 2.0.90", ] [[package]] name = "pyo3-macros-backend" -version = "0.21.2" +version = "0.23.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08260721f32db5e1a5beae69a55553f56b99bd0e1c3e6e0a5e8851a9d0f5a85c" +checksum = "38a385202ff5a92791168b1136afae5059d3ac118457bb7bc304c197c2d33e7d" dependencies = [ - "heck 0.4.1", + "heck 0.5.0", "proc-macro2", "pyo3-build-config", "quote", - "syn 2.0.53", + "syn 2.0.90", +] + +[[package]] +name = "pyo3-stub-gen" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "299c05ff343116c4145aa05428756eb6c5a2226b697347c27312e46261b638aa" +dependencies = [ + "anyhow", + "inventory", + "itertools 0.13.0", + "log", + "maplit", + "num-complex", + "numpy", + "pyo3", + "pyo3-stub-gen-derive", + "serde", + "toml 0.8.19", +] + +[[package]] +name = "pyo3-stub-gen-derive" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "295a22fe8963404c42f3d62c78099dde32ec508a3e756b0dc86a1e7fa604eb34" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", ] [[package]] @@ -4204,9 +4265,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.35" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -4792,7 +4853,7 @@ checksum = "7f81c2fde025af7e69b1d1420531c8a8811ca898919db177141a85313b1cb932" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.90", ] [[package]] @@ -4867,9 +4928,9 @@ checksum = "a3f0bf26fd526d2a95683cd0f87bf103b8539e2ca1ef48ce002d67aad59aa0b4" [[package]] name = "serde" -version = "1.0.197" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] @@ -4906,13 +4967,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.90", ] [[package]] @@ -4926,6 +4987,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -5224,9 +5294,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.53" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", @@ -5242,7 +5312,7 @@ dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.90", ] [[package]] @@ -5393,7 +5463,7 @@ checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.90", ] [[package]] @@ -5495,7 +5565,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.90", ] [[package]] @@ -5592,11 +5662,26 @@ dependencies = [ "serde", ] +[[package]] +name = "toml" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.22.22", +] + [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] [[package]] name = "toml_edit" @@ -5609,6 +5694,19 @@ dependencies = [ "winnow 0.5.40", ] +[[package]] +name = "toml_edit" +version = "0.22.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow 0.6.20", +] + [[package]] name = "tosubcommand" version = "0.1.0" @@ -5624,7 +5722,7 @@ source = "git+https://github.com/zkonduit/enum_to_subcommand#42e9870f1f757932bab dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.90", ] [[package]] @@ -5675,7 +5773,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.90", ] [[package]] @@ -5941,7 +6039,7 @@ dependencies = [ "paste", "serde", "textwrap", - "toml", + "toml 0.5.11", "uniffi_meta", "uniffi_testing", "uniffi_udl", @@ -5965,7 +6063,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a22dbe67c1c957ac6e7611bdf605a6218aa86b0eebeb8be58b70ae85ad7d73dc" dependencies = [ "quote", - "syn 2.0.53", + "syn 2.0.90", ] [[package]] @@ -5996,8 +6094,8 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.53", - "toml", + "syn 2.0.90", + "toml 0.5.11", "uniffi_meta", ] @@ -6199,7 +6297,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.90", "wasm-bindgen-shared", ] @@ -6243,7 +6341,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.90", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6288,7 +6386,7 @@ checksum = "b7f89739351a2e03cb94beb799d47fb2cac01759b40ec441f7de39b00cbf7ef0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.90", ] [[package]] @@ -6574,9 +6672,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.6.5" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" dependencies = [ "memchr", ] @@ -6630,7 +6728,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.90", ] [[package]] @@ -6650,7 +6748,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.90", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 0046e90ae..39bd5c1c2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -79,21 +79,22 @@ tokio = { version = "1.35.0", default-features = false, features = [ "macros", "rt-multi-thread", ], optional = true } -pyo3 = { version = "0.21.2", features = [ +pyo3 = { version = "0.23.2", features = [ "extension-module", "abi3-py37", "macros", ], default-features = false, optional = true } -pyo3-asyncio = { git = "https://github.com/jopemachine/pyo3-asyncio/", branch = "migration-pyo3-0.21", features = [ +pyo3-async-runtimes = { git = "https://github.com/PyO3/pyo3-async-runtimes", version = "0.23.0", features = [ "attributes", "tokio-runtime", ], default-features = false, optional = true } -pyo3-log = { version = "0.10.0", default-features = false, optional = true } +pyo3-log = { version = "0.12.0", default-features = false, optional = true } tract-onnx = { git = "https://github.com/sonos/tract/", rev = "37132e0397d0a73e5bd3a8615d932dabe44f6736", default-features = false, optional = true } tabled = { version = "0.12.0", optional = true } metal = { git = "https://github.com/gfx-rs/metal-rs", optional = true } objc = { version = "0.2.4", optional = true } mimalloc = { version = "0.1", optional = true } +pyo3-stub-gen = { version = "0.6.0", optional = true } # universal bindings uniffi = { version = "=0.28.0", optional = true } @@ -210,6 +211,10 @@ required-features = ["ezkl"] name = "ios_gen_bindings" required-features = ["ios-bindings", "uuid", "camino", "uniffi_bindgen"] +[[bin]] +name = "py_stub_gen" +required-features = ["python-bindings"] + [features] web = ["wasm-bindgen-rayon"] default = [ @@ -220,7 +225,7 @@ default = [ "parallel-poly-read", ] onnx = ["dep:tract-onnx"] -python-bindings = ["pyo3", "pyo3-log", "pyo3-asyncio"] +python-bindings = ["pyo3", "pyo3-log", "pyo3-async-runtimes", "pyo3-stub-gen"] ios-bindings = ["mv-lookup", "precompute-coset", "parallel-poly-read", "uniffi"] ios-bindings-test = ["ios-bindings", "uniffi/bindgen-tests"] ezkl = [ diff --git a/examples/notebooks/felt_conversion_test.ipynb b/examples/notebooks/felt_conversion_test.ipynb new file mode 100644 index 000000000..fd00ecf4e --- /dev/null +++ b/examples/notebooks/felt_conversion_test.ipynb @@ -0,0 +1,130 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'inputs': [['a5c7080000000000000000000000000000000000000000000000000000000000', 'b09c1c0000000000000000000000000000000000000000000000000000000000', '29fe2e0000000000000000000000000000000000000000000000000000000000', '5d7e1a0000000000000000000000000000000000000000000000000000000000', 'f3ed390000000000000000000000000000000000000000000000000000000000', '93bf370000000000000000000000000000000000000000000000000000000000', '5973130000000000000000000000000000000000000000000000000000000000', 'f760370000000000000000000000000000000000000000000000000000000000', 'f79b1b0000000000000000000000000000000000000000000000000000000000', '2dee360000000000000000000000000000000000000000000000000000000000', 'f062370000000000000000000000000000000000000000000000000000000000', '5392270000000000000000000000000000000000000000000000000000000000', '2e64270000000000000000000000000000000000000000000000000000000000', 'd2ee1f0000000000000000000000000000000000000000000000000000000000', '1c194f0000000000000000000000000000000000000000000000000000000000', '06452b0000000000000000000000000000000000000000000000000000000000', 'e777330000000000000000000000000000000000000000000000000000000000', 'e58b3a0000000000000000000000000000000000000000000000000000000000', 'c7132e0000000000000000000000000000000000000000000000000000000000', '299e410000000000000000000000000000000000000000000000000000000000', '29813a0000000000000000000000000000000000000000000000000000000000', 'f7c04d0000000000000000000000000000000000000000000000000000000000', 'f9f7360000000000000000000000000000000000000000000000000000000000', '1a5a320000000000000000000000000000000000000000000000000000000000', '710e330000000000000000000000000000000000000000000000000000000000', 'ae1e4d0000000000000000000000000000000000000000000000000000000000', '8859140000000000000000000000000000000000000000000000000000000000', 'f3cc4e0000000000000000000000000000000000000000000000000000000000', '13970c0000000000000000000000000000000000000000000000000000000000', 'df8c240000000000000000000000000000000000000000000000000000000000', 'adee340000000000000000000000000000000000000000000000000000000000', '25b1330000000000000000000000000000000000000000000000000000000000', '43dd300000000000000000000000000000000000000000000000000000000000', 'fa2f2e0000000000000000000000000000000000000000000000000000000000', '68793d0000000000000000000000000000000000000000000000000000000000', '103b080000000000000000000000000000000000000000000000000000000000', 'fcca350000000000000000000000000000000000000000000000000000000000', '1b14370000000000000000000000000000000000000000000000000000000000', '75a5390000000000000000000000000000000000000000000000000000000000', 'a703150000000000000000000000000000000000000000000000000000000000', '5bb22e0000000000000000000000000000000000000000000000000000000000', 'e01e170000000000000000000000000000000000000000000000000000000000', '34f2400000000000000000000000000000000000000000000000000000000000', 'e68f4d0000000000000000000000000000000000000000000000000000000000', 'c230170000000000000000000000000000000000000000000000000000000000', '79392c0000000000000000000000000000000000000000000000000000000000', '6d16100000000000000000000000000000000000000000000000000000000000', 'd9c71d0000000000000000000000000000000000000000000000000000000000', 'ed5a460000000000000000000000000000000000000000000000000000000000', '150d190000000000000000000000000000000000000000000000000000000000', 'fbea330000000000000000000000000000000000000000000000000000000000', '051c1f0000000000000000000000000000000000000000000000000000000000', 'c2c30e0000000000000000000000000000000000000000000000000000000000', '767e0a0000000000000000000000000000000000000000000000000000000000', '38d80c0000000000000000000000000000000000000000000000000000000000', 'c6b5390000000000000000000000000000000000000000000000000000000000', 'd4e63f0000000000000000000000000000000000000000000000000000000000', 'bd1c150000000000000000000000000000000000000000000000000000000000', 'fa02490000000000000000000000000000000000000000000000000000000000', '85aa080000000000000000000000000000000000000000000000000000000000', '844e190000000000000000000000000000000000000000000000000000000000', '8439330000000000000000000000000000000000000000000000000000000000', '3aba270000000000000000000000000000000000000000000000000000000000', '67ae140000000000000000000000000000000000000000000000000000000000', 'eb23240000000000000000000000000000000000000000000000000000000000', 'a8980b0000000000000000000000000000000000000000000000000000000000', '85893f0000000000000000000000000000000000000000000000000000000000', '2129410000000000000000000000000000000000000000000000000000000000', '5312220000000000000000000000000000000000000000000000000000000000', '96e4250000000000000000000000000000000000000000000000000000000000', '95b01b0000000000000000000000000000000000000000000000000000000000', '1ac2120000000000000000000000000000000000000000000000000000000000', 'e4da250000000000000000000000000000000000000000000000000000000000', '18ef4b0000000000000000000000000000000000000000000000000000000000', '050f260000000000000000000000000000000000000000000000000000000000', '1dbb340000000000000000000000000000000000000000000000000000000000', '9294090000000000000000000000000000000000000000000000000000000000', '1394190000000000000000000000000000000000000000000000000000000000', 'e04a4e0000000000000000000000000000000000000000000000000000000000', '1835450000000000000000000000000000000000000000000000000000000000', '44a84c0000000000000000000000000000000000000000000000000000000000', '922b200000000000000000000000000000000000000000000000000000000000', '91d03d0000000000000000000000000000000000000000000000000000000000', 'db3e490000000000000000000000000000000000000000000000000000000000', 'c151480000000000000000000000000000000000000000000000000000000000', '74090e0000000000000000000000000000000000000000000000000000000000', '9f33170000000000000000000000000000000000000000000000000000000000', 'f3652b0000000000000000000000000000000000000000000000000000000000', 'ab2e230000000000000000000000000000000000000000000000000000000000', '94f3130000000000000000000000000000000000000000000000000000000000', '41173a0000000000000000000000000000000000000000000000000000000000', '7917340000000000000000000000000000000000000000000000000000000000', '26aa2d0000000000000000000000000000000000000000000000000000000000', 'b8ef400000000000000000000000000000000000000000000000000000000000', 'f731410000000000000000000000000000000000000000000000000000000000', '22ef2a0000000000000000000000000000000000000000000000000000000000', '71b12d0000000000000000000000000000000000000000000000000000000000', '9fa4380000000000000000000000000000000000000000000000000000000000', 'f3f2420000000000000000000000000000000000000000000000000000000000', 'af35330000000000000000000000000000000000000000000000000000000000']], 'outputs': [['a5c7080000000000000000000000000000000000000000000000000000000000', 'b09c1c0000000000000000000000000000000000000000000000000000000000', '29fe2e0000000000000000000000000000000000000000000000000000000000', '5d7e1a0000000000000000000000000000000000000000000000000000000000', 'f3ed390000000000000000000000000000000000000000000000000000000000', '93bf370000000000000000000000000000000000000000000000000000000000', '5973130000000000000000000000000000000000000000000000000000000000', 'f760370000000000000000000000000000000000000000000000000000000000', 'f79b1b0000000000000000000000000000000000000000000000000000000000', '2dee360000000000000000000000000000000000000000000000000000000000', 'f062370000000000000000000000000000000000000000000000000000000000', '5392270000000000000000000000000000000000000000000000000000000000', '2e64270000000000000000000000000000000000000000000000000000000000', 'd2ee1f0000000000000000000000000000000000000000000000000000000000', '1c194f0000000000000000000000000000000000000000000000000000000000', '06452b0000000000000000000000000000000000000000000000000000000000', 'e777330000000000000000000000000000000000000000000000000000000000', 'e58b3a0000000000000000000000000000000000000000000000000000000000', 'c7132e0000000000000000000000000000000000000000000000000000000000', '299e410000000000000000000000000000000000000000000000000000000000', '29813a0000000000000000000000000000000000000000000000000000000000', 'f7c04d0000000000000000000000000000000000000000000000000000000000', 'f9f7360000000000000000000000000000000000000000000000000000000000', '1a5a320000000000000000000000000000000000000000000000000000000000', '710e330000000000000000000000000000000000000000000000000000000000', 'ae1e4d0000000000000000000000000000000000000000000000000000000000', '8859140000000000000000000000000000000000000000000000000000000000', 'f3cc4e0000000000000000000000000000000000000000000000000000000000', '13970c0000000000000000000000000000000000000000000000000000000000', 'df8c240000000000000000000000000000000000000000000000000000000000', 'adee340000000000000000000000000000000000000000000000000000000000', '25b1330000000000000000000000000000000000000000000000000000000000', '43dd300000000000000000000000000000000000000000000000000000000000', 'fa2f2e0000000000000000000000000000000000000000000000000000000000', '68793d0000000000000000000000000000000000000000000000000000000000', '103b080000000000000000000000000000000000000000000000000000000000', 'fcca350000000000000000000000000000000000000000000000000000000000', '1b14370000000000000000000000000000000000000000000000000000000000', '75a5390000000000000000000000000000000000000000000000000000000000', 'a703150000000000000000000000000000000000000000000000000000000000', '5bb22e0000000000000000000000000000000000000000000000000000000000', 'e01e170000000000000000000000000000000000000000000000000000000000', '34f2400000000000000000000000000000000000000000000000000000000000', 'e68f4d0000000000000000000000000000000000000000000000000000000000', 'c230170000000000000000000000000000000000000000000000000000000000', '79392c0000000000000000000000000000000000000000000000000000000000', '6d16100000000000000000000000000000000000000000000000000000000000', 'd9c71d0000000000000000000000000000000000000000000000000000000000', 'ed5a460000000000000000000000000000000000000000000000000000000000', '150d190000000000000000000000000000000000000000000000000000000000', 'fbea330000000000000000000000000000000000000000000000000000000000', '051c1f0000000000000000000000000000000000000000000000000000000000', 'c2c30e0000000000000000000000000000000000000000000000000000000000', '767e0a0000000000000000000000000000000000000000000000000000000000', '38d80c0000000000000000000000000000000000000000000000000000000000', 'c6b5390000000000000000000000000000000000000000000000000000000000', 'd4e63f0000000000000000000000000000000000000000000000000000000000', 'bd1c150000000000000000000000000000000000000000000000000000000000', 'fa02490000000000000000000000000000000000000000000000000000000000', '85aa080000000000000000000000000000000000000000000000000000000000', '844e190000000000000000000000000000000000000000000000000000000000', '8439330000000000000000000000000000000000000000000000000000000000', '3aba270000000000000000000000000000000000000000000000000000000000', '67ae140000000000000000000000000000000000000000000000000000000000', 'eb23240000000000000000000000000000000000000000000000000000000000', 'a8980b0000000000000000000000000000000000000000000000000000000000', '85893f0000000000000000000000000000000000000000000000000000000000', '2129410000000000000000000000000000000000000000000000000000000000', '5312220000000000000000000000000000000000000000000000000000000000', '96e4250000000000000000000000000000000000000000000000000000000000', '95b01b0000000000000000000000000000000000000000000000000000000000', '1ac2120000000000000000000000000000000000000000000000000000000000', 'e4da250000000000000000000000000000000000000000000000000000000000', '18ef4b0000000000000000000000000000000000000000000000000000000000', '050f260000000000000000000000000000000000000000000000000000000000', '1dbb340000000000000000000000000000000000000000000000000000000000', '9294090000000000000000000000000000000000000000000000000000000000', '1394190000000000000000000000000000000000000000000000000000000000', 'e04a4e0000000000000000000000000000000000000000000000000000000000', '1835450000000000000000000000000000000000000000000000000000000000', '44a84c0000000000000000000000000000000000000000000000000000000000', '922b200000000000000000000000000000000000000000000000000000000000', '91d03d0000000000000000000000000000000000000000000000000000000000', 'db3e490000000000000000000000000000000000000000000000000000000000', 'c151480000000000000000000000000000000000000000000000000000000000', '74090e0000000000000000000000000000000000000000000000000000000000', '9f33170000000000000000000000000000000000000000000000000000000000', 'f3652b0000000000000000000000000000000000000000000000000000000000', 'ab2e230000000000000000000000000000000000000000000000000000000000', '94f3130000000000000000000000000000000000000000000000000000000000', '41173a0000000000000000000000000000000000000000000000000000000000', '7917340000000000000000000000000000000000000000000000000000000000', '26aa2d0000000000000000000000000000000000000000000000000000000000', 'b8ef400000000000000000000000000000000000000000000000000000000000', 'f731410000000000000000000000000000000000000000000000000000000000', '22ef2a0000000000000000000000000000000000000000000000000000000000', '71b12d0000000000000000000000000000000000000000000000000000000000', '9fa4380000000000000000000000000000000000000000000000000000000000', 'f3f2420000000000000000000000000000000000000000000000000000000000', 'af35330000000000000000000000000000000000000000000000000000000000']], 'max_lookup_inputs': 0, 'min_lookup_inputs': 0, 'max_range_size': 0}\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/dante/Documents/GitHub/ezkl/.env/lib/python3.12/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", + " from .autonotebook import tqdm as notebook_tqdm\n" + ] + } + ], + "source": [ + "\n", + "\n", + "import torch\n", + "import ezkl\n", + "import json\n", + "import subprocess\n", + "from pathlib import Path\n", + "\n", + "\n", + "class Passthrough(torch.nn.Module):\n", + " def __init__(self, input_size=100):\n", + " super().__init__()\n", + "\n", + " def forward(self, x):\n", + " return x\n", + "\n", + "def generate_random_data(size=100, min_val=1, max_val=10):\n", + " return [min_val + (max_val - min_val) * torch.rand(1).item() for _ in range(size)]\n", + "\n", + "def save_json(data, filename):\n", + " with open(filename, 'w') as f:\n", + " json.dump(data, f)\n", + "\n", + "async def run_ezkl_pipeline():\n", + " gip_run_args = ezkl.PyRunArgs()\n", + " gip_run_args.input_visibility = \"public\"\n", + " gip_run_args.output_visibility = \"public\" # no parameters used\n", + " gip_run_args.param_visibility = \"fixed\"\n", + " gip_run_args.input_scale = 19\n", + " gip_run_args.param_scale = 19\n", + " gip_run_args.logrows = 8\n", + " run_args = ezkl.gen_settings(py_run_args=gip_run_args)\n", + " ezkl.get_srs(commitment=ezkl.PyCommitments.KZG)\n", + " ezkl.compile_circuit()\n", + " res = await ezkl.gen_witness()\n", + " print(res)\n", + " ezkl.setup()\n", + " ezkl.prove(proof_path=\"proof.json\")\n", + " ezkl.verify()\n", + "\n", + "def verify_proof_matches_input():\n", + " settings = json.load(open(\"settings.json\"))\n", + " inputs = json.load(open(\"input.json\"))\n", + " proof = json.load(open(\"proof.json\"))\n", + "\n", + " input_scale = settings[\"model_input_scales\"][0]\n", + " model_shapes = settings[\"model_instance_shapes\"]\n", + "\n", + " flat_inputs = [x for arr in inputs[\"input_data\"] for x in arr]\n", + " scaled_inputs = [ezkl.float_to_felt(x, input_scale, ezkl.PyInputType.F32) for x in flat_inputs]\n", + " proof_instances = proof[\"instances\"][0]\n", + "\n", + " def get_group_index(i):\n", + " pos = 0\n", + " for idx, (batch, length) in enumerate(model_shapes):\n", + " next_pos = pos + (batch * length)\n", + " if i < next_pos:\n", + " return idx\n", + " pos = next_pos\n", + " raise IndexError(\"Index out of bounds\")\n", + "\n", + " for i, (scaled, instance) in enumerate(zip(scaled_inputs, proof_instances)):\n", + " group_idx = get_group_index(i)\n", + " _, length = model_shapes[group_idx]\n", + "\n", + " descaled_instance = ezkl.felt_to_float(instance, input_scale)\n", + " descaled_input = ezkl.felt_to_float(scaled, input_scale)\n", + " pretty_value = proof[\"pretty_public_inputs\"][\"rescaled_inputs\"][group_idx][i % length]\n", + "\n", + " assert scaled == instance, f\"Input mismatch at index {i}: {scaled} != {instance} ({descaled_instance} != {descaled_input} OG {flat_inputs[i]} PRETTY {pretty_value})\"\n", + "\n", + "model = Passthrough()\n", + "torch.onnx.export(model, torch.randn(1, 100), \"network.onnx\")\n", + "\n", + "input_data = {\"input_data\": [generate_random_data()]}\n", + "save_json(input_data, \"input.json\")\n", + "save_json({\"input_data\": [generate_random_data()]}, \"calibration.json\")\n", + "\n", + "await run_ezkl_pipeline()\n", + "verify_proof_matches_input()\n", + "\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".env", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.7" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/ezkl.pyi b/ezkl.pyi new file mode 100644 index 000000000..b5d38193d --- /dev/null +++ b/ezkl.pyi @@ -0,0 +1,851 @@ +# This file is automatically generated by pyo3_stub_gen +# ruff: noqa: E501, F401 + +import os +import pathlib +import typing +from enum import Enum, auto + +class PyG1: + r""" + pyclass containing the struct used for G1, this is mostly a helper class + """ + ... + +class PyG1Affine: + r""" + pyclass containing the struct used for G1 + """ + ... + +class PyRunArgs: + r""" + Python class containing the struct used for run_args + + Returns + ------- + PyRunArgs + """ + ... + +class PyCommitments(Enum): + r""" + pyclass representing an enum, denoting the type of commitment + """ + KZG = auto() + IPA = auto() + +class PyInputType(Enum): + Bool = auto() + F16 = auto() + F32 = auto() + F64 = auto() + Int = auto() + TDim = auto() + +class PyTestDataSource(Enum): + r""" + pyclass representing an enum + """ + File = auto() + OnChain = auto() + +def aggregate(aggregation_snarks:typing.Sequence[str | os.PathLike | pathlib.Path],proof_path:str | os.PathLike | pathlib.Path,vk_path:str | os.PathLike | pathlib.Path,transcript:str,logrows:int,check_mode:str,split_proofs:bool,srs_path:typing.Optional[str | os.PathLike | pathlib.Path],commitment:PyCommitments) -> bool: + r""" + Creates an aggregated proof + + Arguments + --------- + aggregation_snarks: list[str] + List of paths to the various proofs + + proof_path: str + Path to output the aggregated proof + + vk_path: str + Path to the VK file + + transcript: + Proof transcript type to be used. `evm` used by default. `poseidon` is also supported + + logrows: + Logrows used for aggregation circuit + + check_mode: str + Run sanity checks during calculations. Accepts `safe` or `unsafe` + + split-proofs: bool + Whether the accumulated proofs are segments of a larger circuit + + srs_path: str + Path to the SRS used + + commitment: str + Accepts "kzg" or "ipa" + + Returns + ------- + bool + """ + ... + +def buffer_to_felts(buffer:typing.Sequence[int]) -> list[str]: + r""" + Converts a buffer to vector of field elements + + Arguments + ------- + buffer: list[int] + List of integers representing a buffer + + Returns + ------- + list[str] + List of field elements represented as strings + """ + ... + +def calibrate_settings(data:str | os.PathLike | pathlib.Path,model:str | os.PathLike | pathlib.Path,settings:str | os.PathLike | pathlib.Path,target:str,lookup_safety_margin:float,scales:typing.Optional[typing.Sequence[int]],scale_rebase_multiplier:typing.Sequence[int],max_logrows:typing.Optional[int]) -> typing.Any: + r""" + Calibrates the circuit settings + + Arguments + --------- + data: str + Path to the calibration data + + model: str + Path to the onnx file + + settings: str + Path to the settings file + + lookup_safety_margin: int + the lookup safety margin to use for calibration. if the max lookup is 2^k, then the max lookup will be 2^k * lookup_safety_margin. larger = safer but slower + + scales: list[int] + Optional scales to specifically try for calibration + + scale_rebase_multiplier: list[int] + Optional scale rebase multipliers to specifically try for calibration. This is the multiplier at which we divide to return to the input scale. + + max_logrows: int + Optional max logrows to use for calibration + + + Returns + ------- + bool + """ + ... + +def compile_circuit(model:str | os.PathLike | pathlib.Path,compiled_circuit:str | os.PathLike | pathlib.Path,settings_path:str | os.PathLike | pathlib.Path) -> bool: + r""" + Compiles the circuit for use in other steps + + Arguments + --------- + model: str + Path to the onnx model file + + compiled_circuit: str + Path to output the compiled circuit + + settings_path: str + Path to the settings files + + Returns + ------- + bool + """ + ... + +def create_evm_data_attestation(input_data:str | os.PathLike | pathlib.Path,settings_path:str | os.PathLike | pathlib.Path,sol_code_path:str | os.PathLike | pathlib.Path,abi_path:str | os.PathLike | pathlib.Path,witness_path:typing.Optional[str | os.PathLike | pathlib.Path]) -> typing.Any: + r""" + Creates an EVM compatible data attestation verifier, you will need solc installed in your environment to run this + + Arguments + --------- + input_data: str + The path to the .json data file, which should contain the necessary calldata and account addresses needed to read from all the on-chain view functions that return the data that the network ingests as inputs + + settings_path: str + The path to the settings file + + sol_code_path: str + The path to the create the solidity verifier + + abi_path: str + The path to create the ABI for the solidity verifier + + Returns + ------- + bool + """ + ... + +def create_evm_verifier(vk_path:str | os.PathLike | pathlib.Path,settings_path:str | os.PathLike | pathlib.Path,sol_code_path:str | os.PathLike | pathlib.Path,abi_path:str | os.PathLike | pathlib.Path,srs_path:typing.Optional[str | os.PathLike | pathlib.Path],reusable:bool) -> typing.Any: + r""" + Creates an EVM compatible verifier, you will need solc installed in your environment to run this + + Arguments + --------- + vk_path: str + The path to the verification key file + + settings_path: str + The path to the settings file + + sol_code_path: str + The path to the create the solidity verifier + + abi_path: str + The path to create the ABI for the solidity verifier + + srs_path: str + The path to the SRS file + + reusable: bool + Whether the verifier should be rendered as a reusable contract. If so, then you will need to deploy the VK artifact separately which you can generate using the create_evm_vka command + + Returns + ------- + bool + """ + ... + +def create_evm_verifier_aggr(aggregation_settings:typing.Sequence[str | os.PathLike | pathlib.Path],vk_path:str | os.PathLike | pathlib.Path,sol_code_path:str | os.PathLike | pathlib.Path,abi_path:str | os.PathLike | pathlib.Path,logrows:int,srs_path:typing.Optional[str | os.PathLike | pathlib.Path],reusable:bool) -> typing.Any: + r""" + Creates an evm compatible aggregate verifier, you will need solc installed in your environment to run this + + Arguments + --------- + aggregation_settings: str + path to the settings file + + vk_path: str + The path to load the desired verification key file + + sol_code_path: str + The path to the Solidity code + + abi_path: str + The path to output the Solidity verifier ABI + + logrows: int + Number of logrows used during aggregated setup + + srs_path: str + The path to the SRS file + + reusable: bool + Whether the verifier should be rendered as a reusable contract. If so, then you will need to deploy the VK artifact separately which you can generate using the create_evm_vka command + + Returns + ------- + bool + """ + ... + +def create_evm_vka(vk_path:str | os.PathLike | pathlib.Path,settings_path:str | os.PathLike | pathlib.Path,sol_code_path:str | os.PathLike | pathlib.Path,abi_path:str | os.PathLike | pathlib.Path,srs_path:typing.Optional[str | os.PathLike | pathlib.Path]) -> typing.Any: + r""" + Creates an Evm VK artifact. This command generated a VK with circuit specific meta data encoding in memory for use by the reusable H2 verifier. + This is useful for deploying verifier that were otherwise too big to fit on chain and required aggregation. + + Arguments + --------- + vk_path: str + The path to the verification key file + + settings_path: str + The path to the settings file + + sol_code_path: str + The path to the create the solidity verifying key. + + abi_path: str + The path to create the ABI for the solidity verifier + + srs_path: str + The path to the SRS file + + Returns + ------- + bool + """ + ... + +def deploy_da_evm(addr_path:str | os.PathLike | pathlib.Path,input_data:str | os.PathLike | pathlib.Path,settings_path:str | os.PathLike | pathlib.Path,sol_code_path:str | os.PathLike | pathlib.Path,rpc_url:typing.Optional[str],optimizer_runs:int,private_key:typing.Optional[str]) -> typing.Any: + r""" + deploys the solidity da verifier + """ + ... + +def deploy_evm(addr_path:str | os.PathLike | pathlib.Path,sol_code_path:str | os.PathLike | pathlib.Path,rpc_url:typing.Optional[str],contract_type:str,optimizer_runs:int,private_key:typing.Optional[str]) -> typing.Any: + r""" + deploys the solidity verifier + """ + ... + +def encode_evm_calldata(proof:str | os.PathLike | pathlib.Path,calldata:str | os.PathLike | pathlib.Path,addr_vk:typing.Optional[str]) -> list[int]: + r""" + Creates encoded evm calldata from a proof file + + Arguments + --------- + proof: str + Path to the proof file + + calldata: str + Path to the calldata file to save + + addr_vk: str + The address of the verification key contract (if the verifier key is to be rendered as a separate contract) + + Returns + ------- + vec[u8] + The encoded calldata + """ + ... + +def felt_to_big_endian(felt:str) -> str: + r""" + Converts a field element hex string to big endian + + Arguments + ------- + felt: str + The field element represented as a string + + + Returns + ------- + str + field element represented as a string + """ + ... + +def felt_to_float(felt:str,scale:int) -> float: + r""" + Converts a field element hex string to a floating point number + + Arguments + ------- + felt: str + The field element represented as a string + + scale: float + The scaling factor used to convert the field element into a floating point representation + + Returns + ------- + float + """ + ... + +def felt_to_int(felt:str) -> int: + r""" + Converts a field element hex string to an integer + + Arguments + ------- + felt: str + The field element represented as a string + + Returns + ------- + int + """ + ... + +def float_to_felt(input:float,scale:int,input_type:PyInputType) -> str: + r""" + Converts a floating point element to a field element hex string + + Arguments + ------- + input: float + The field element represented as a string + + scale: float + The scaling factor used to quantize the float into a field element + + input_type: PyInputType + The type of the input + + Returns + ------- + str + The field element represented as a string + """ + ... + +def gen_settings(model:str | os.PathLike | pathlib.Path,output:str | os.PathLike | pathlib.Path,py_run_args:typing.Optional[PyRunArgs]) -> bool: + r""" + Generates the circuit settings + + Arguments + --------- + model: str + Path to the onnx file + + output: str + Path to create the settings file + + py_run_args: PyRunArgs + PyRunArgs object to initialize the settings + + Returns + ------- + bool + """ + ... + +def gen_srs(srs_path:str | os.PathLike | pathlib.Path,logrows:int) -> None: + r""" + Generates the Structured Reference String (SRS), use this only for testing purposes + + Arguments + --------- + srs_path: str + Path to the create the SRS file + + logrows: int + The number of logrows for the SRS file + """ + ... + +def gen_vk_from_pk_aggr(path_to_pk:str | os.PathLike | pathlib.Path,vk_output_path:str | os.PathLike | pathlib.Path) -> bool: + r""" + Generates a vk from a pk for an aggregate circuit and saves it to a file + + Arguments + ------- + path_to_pk: str + Path to the proving key + + vk_output_path: str + Path to create the vk file + + Returns + ------- + bool + """ + ... + +def gen_vk_from_pk_single(path_to_pk:str | os.PathLike | pathlib.Path,circuit_settings_path:str | os.PathLike | pathlib.Path,vk_output_path:str | os.PathLike | pathlib.Path) -> bool: + r""" + Generates a vk from a pk for a model circuit and saves it to a file + + Arguments + ------- + path_to_pk: str + Path to the proving key + + circuit_settings_path: str + Path to the witness file + + vk_output_path: str + Path to create the vk file + + Returns + ------- + bool + """ + ... + +def gen_witness(data:str | os.PathLike | pathlib.Path,model:str | os.PathLike | pathlib.Path,output:typing.Optional[str | os.PathLike | pathlib.Path],vk_path:typing.Optional[str | os.PathLike | pathlib.Path],srs_path:typing.Optional[str | os.PathLike | pathlib.Path]) -> typing.Any: + r""" + Runs the forward pass operation to generate a witness + + Arguments + --------- + data: str + Path to the data file + + model: str + Path to the compiled model file + + output: str + Path to create the witness file + + vk_path: str + Path to the verification key + + srs_path: str + Path to the SRS file + + Returns + ------- + dict + Python object containing the witness values + """ + ... + +def get_srs(settings_path:typing.Optional[str | os.PathLike | pathlib.Path],logrows:typing.Optional[int],srs_path:typing.Optional[str | os.PathLike | pathlib.Path],commitment:typing.Optional[PyCommitments]) -> typing.Any: + r""" + Gets a public srs + + Arguments + --------- + settings_path: str + Path to the settings file + + logrows: int + The number of logrows for the SRS file + + srs_path: str + Path to the create the SRS file + + commitment: str + Specify the commitment used ("kzg", "ipa") + + Returns + ------- + bool + """ + ... + +def ipa_commit(message:typing.Sequence[str],vk_path:str | os.PathLike | pathlib.Path,settings_path:str | os.PathLike | pathlib.Path,srs_path:typing.Optional[str | os.PathLike | pathlib.Path]) -> list[PyG1Affine]: + r""" + Generate an ipa commitment. + + Arguments + ------- + message: list[str] + List of field elements represnted as strings + + vk_path: str + Path to the verification key + + settings_path: str + Path to the settings file + + srs_path: str + Path to the Structure Reference String (SRS) file + + Returns + ------- + list[PyG1Affine] + """ + ... + +def kzg_commit(message:typing.Sequence[str],vk_path:str | os.PathLike | pathlib.Path,settings_path:str | os.PathLike | pathlib.Path,srs_path:typing.Optional[str | os.PathLike | pathlib.Path]) -> list[PyG1Affine]: + r""" + Generate a kzg commitment. + + Arguments + ------- + message: list[str] + List of field elements represnted as strings + + vk_path: str + Path to the verification key + + settings_path: str + Path to the settings file + + srs_path: str + Path to the Structure Reference String (SRS) file + + Returns + ------- + list[PyG1Affine] + """ + ... + +def mock(witness:str | os.PathLike | pathlib.Path,model:str | os.PathLike | pathlib.Path) -> bool: + r""" + Mocks the prover + + Arguments + --------- + witness: str + Path to the witness file + + model: str + Path to the compiled model file + + Returns + ------- + bool + """ + ... + +def mock_aggregate(aggregation_snarks:typing.Sequence[str | os.PathLike | pathlib.Path],logrows:int,split_proofs:bool) -> bool: + r""" + Mocks the aggregate prover + + Arguments + --------- + aggregation_snarks: list[str] + List of paths to the relevant proof files + + logrows: int + Number of logrows to use for the aggregation circuit + + split_proofs: bool + Indicates whether the accumulated are segments of a larger proof + + Returns + ------- + bool + """ + ... + +def poseidon_hash(message:typing.Sequence[str]) -> list[str]: + r""" + Generate a poseidon hash. + + Arguments + ------- + message: list[str] + List of field elements represented as strings + + Returns + ------- + list[str] + List of field elements represented as strings + """ + ... + +def prove(witness:str | os.PathLike | pathlib.Path,model:str | os.PathLike | pathlib.Path,pk_path:str | os.PathLike | pathlib.Path,proof_path:typing.Optional[str | os.PathLike | pathlib.Path],proof_type:str,srs_path:typing.Optional[str | os.PathLike | pathlib.Path]) -> typing.Any: + r""" + Runs the prover on a set of inputs + + Arguments + --------- + witness: str + Path to the witness file + + model: str + Path to the compiled model file + + pk_path: str + Path to the proving key file + + proof_path: str + Path to create the proof file + + proof_type: str + Accepts `single`, `for-aggr` + + srs_path: str + Path to the SRS file + + Returns + ------- + bool + """ + ... + +def setup(model:str | os.PathLike | pathlib.Path,vk_path:str | os.PathLike | pathlib.Path,pk_path:str | os.PathLike | pathlib.Path,srs_path:typing.Optional[str | os.PathLike | pathlib.Path],witness_path:typing.Optional[str | os.PathLike | pathlib.Path],disable_selector_compression:bool) -> bool: + r""" + Runs the setup process + + Arguments + --------- + model: str + Path to the compiled model file + + vk_path: str + Path to create the verification key file + + pk_path: str + Path to create the proving key file + + srs_path: str + Path to the SRS file + + witness_path: str + Path to the witness file + + disable_selector_compression: bool + Whether to compress the selectors or not + + Returns + ------- + bool + """ + ... + +def setup_aggregate(sample_snarks:typing.Sequence[str | os.PathLike | pathlib.Path],vk_path:str | os.PathLike | pathlib.Path,pk_path:str | os.PathLike | pathlib.Path,logrows:int,split_proofs:bool,srs_path:typing.Optional[str | os.PathLike | pathlib.Path],disable_selector_compression:bool,commitment:PyCommitments) -> bool: + r""" + Runs the setup process for an aggregate setup + + Arguments + --------- + sample_snarks: list[str] + List of paths to the various proofs + + vk_path: str + Path to create the aggregated VK + + pk_path: str + Path to create the aggregated PK + + logrows: int + Number of logrows to use + + split_proofs: bool + Whether the accumulated are segments of a larger proof + + srs_path: str + Path to the SRS file + + disable_selector_compression: bool + Whether to compress selectors + + commitment: str + Accepts `kzg`, `ipa` + + Returns + ------- + bool + """ + ... + +def setup_test_evm_witness(data_path:str | os.PathLike | pathlib.Path,compiled_circuit_path:str | os.PathLike | pathlib.Path,test_data:str | os.PathLike | pathlib.Path,input_source:PyTestDataSource,output_source:PyTestDataSource,rpc_url:typing.Optional[str]) -> typing.Any: + r""" + Setup test evm witness + + Arguments + --------- + data_path: str + The path to the .json data file, which should include both the network input (possibly private) and the network output (public input to the proof) + + compiled_circuit_path: str + The path to the compiled model file (generated using the compile-circuit command) + + test_data: str + For testing purposes only. The optional path to the .json data file that will be generated that contains the OnChain data storage information derived from the file information in the data .json file. Should include both the network input (possibly private) and the network output (public input to the proof) + + input_sources: str + Where the input data comes from + + output_source: str + Where the output data comes from + + rpc_url: str + RPC URL for an EVM compatible node, if None, uses Anvil as a local RPC node + + Returns + ------- + bool + """ + ... + +def swap_proof_commitments(proof_path:str | os.PathLike | pathlib.Path,witness_path:str | os.PathLike | pathlib.Path) -> None: + r""" + Swap the commitments in a proof + + Arguments + ------- + proof_path: str + Path to the proof file + + witness_path: str + Path to the witness file + """ + ... + +def table(model:str | os.PathLike | pathlib.Path,py_run_args:typing.Optional[PyRunArgs]) -> str: + r""" + Displays the table as a string in python + + Arguments + --------- + model: str + Path to the onnx file + + Returns + --------- + str + Table of the nodes in the onnx file + """ + ... + +def verify(proof_path:str | os.PathLike | pathlib.Path,settings_path:str | os.PathLike | pathlib.Path,vk_path:str | os.PathLike | pathlib.Path,srs_path:typing.Optional[str | os.PathLike | pathlib.Path],reduced_srs:bool) -> bool: + r""" + Verifies a given proof + + Arguments + --------- + proof_path: str + Path to create the proof file + + settings_path: str + Path to the settings file + + vk_path: str + Path to the verification key file + + srs_path: str + Path to the SRS file + + non_reduced_srs: bool + Whether to reduce the number of SRS logrows to the number of instances rather than the number of logrows used for proofs (only works if the srs were generated in the same ceremony) + + Returns + ------- + bool + """ + ... + +def verify_aggr(proof_path:str | os.PathLike | pathlib.Path,vk_path:str | os.PathLike | pathlib.Path,logrows:int,commitment:PyCommitments,reduced_srs:bool,srs_path:typing.Optional[str | os.PathLike | pathlib.Path]) -> bool: + r""" + Verifies and aggregate proof + + Arguments + --------- + proof_path: str + The path to the proof file + + vk_path: str + The path to the verification key file + + logrows: int + logrows used for aggregation circuit + + commitment: str + Accepts "kzg" or "ipa" + + reduced_srs: bool + Whether to reduce the number of SRS logrows to the number of instances rather than the number of logrows used for proofs (only works if the srs were generated in the same ceremony) + + srs_path: str + The path to the SRS file + + Returns + ------- + bool + """ + ... + +def verify_evm(addr_verifier:str,proof_path:str | os.PathLike | pathlib.Path,rpc_url:typing.Optional[str],addr_da:typing.Optional[str],addr_vk:typing.Optional[str]) -> typing.Any: + r""" + verifies an evm compatible proof, you will need solc installed in your environment to run this + + Arguments + --------- + addr_verifier: str + The verifier contract's address as a hex string + + proof_path: str + The path to the proof file (generated using the prove command) + + rpc_url: str + RPC URL for an Ethereum node, if None will use Anvil but WON'T persist state + + addr_da: str + does the verifier use data attestation ? + + addr_vk: str + The addess of the separate VK contract (if the verifier key is rendered as a separate contract) + Returns + ------- + bool + """ + ... + diff --git a/src/bin/py_stub_gen.rs b/src/bin/py_stub_gen.rs new file mode 100644 index 000000000..a7e1b6d57 --- /dev/null +++ b/src/bin/py_stub_gen.rs @@ -0,0 +1,9 @@ +use pyo3_stub_gen::Result; + +fn main() -> Result<()> { + // `stub_info` is a function defined by `define_stub_info_gatherer!` macro. + env_logger::Builder::from_env(env_logger::Env::default().filter_or("RUST_LOG", "info")).init(); + let stub = ezkl::bindings::python::stub_info()?; + stub.generate()?; + Ok(()) +} diff --git a/src/bindings/python.rs b/src/bindings/python.rs index 06b0d9f78..14c840be0 100644 --- a/src/bindings/python.rs +++ b/src/bindings/python.rs @@ -4,6 +4,7 @@ use crate::circuit::modules::poseidon::{ PoseidonChip, }; use crate::circuit::modules::Module; +use crate::circuit::InputType; use crate::circuit::{CheckMode, Tolerance}; use crate::commands::*; use crate::fieldutils::{felt_to_integer_rep, integer_rep_to_felt, IntegerRep}; @@ -26,7 +27,12 @@ use pyo3::exceptions::{PyIOError, PyRuntimeError}; use pyo3::prelude::*; use pyo3::wrap_pyfunction; use pyo3_log; +use pyo3_stub_gen::{ + define_stub_info_gatherer, derive::gen_stub_pyclass, derive::gen_stub_pyclass_enum, + derive::gen_stub_pyfunction, TypeInfo, +}; use snark_verifier::util::arithmetic::PrimeField; +use std::collections::HashSet; use std::str::FromStr; use std::{fs::File, path::PathBuf}; @@ -35,6 +41,7 @@ type PyFelt = String; /// pyclass representing an enum #[pyclass] #[derive(Debug, Clone)] +#[gen_stub_pyclass_enum] enum PyTestDataSource { /// The data is loaded from a file File, @@ -54,6 +61,7 @@ impl From for TestDataSource { /// pyclass containing the struct used for G1, this is mostly a helper class #[pyclass] #[derive(Debug, Clone)] +#[gen_stub_pyclass] struct PyG1 { #[pyo3(get, set)] /// Field Element representing x @@ -100,6 +108,7 @@ impl pyo3::ToPyObject for PyG1 { /// pyclass containing the struct used for G1 #[pyclass] #[derive(Debug, Clone)] +#[gen_stub_pyclass] pub struct PyG1Affine { #[pyo3(get, set)] /// @@ -145,6 +154,7 @@ impl pyo3::ToPyObject for PyG1Affine { /// #[pyclass] #[derive(Clone)] +#[gen_stub_pyclass] struct PyRunArgs { #[pyo3(get, set)] /// float: The tolerance for error on model outputs @@ -259,6 +269,7 @@ impl Into for RunArgs { #[pyclass] #[derive(Debug, Clone)] +#[gen_stub_pyclass_enum] /// pyclass representing an enum, denoting the type of commitment pub enum PyCommitments { /// KZG commitment @@ -306,6 +317,65 @@ impl FromStr for PyCommitments { } } +#[pyclass] +#[derive(Debug, Clone)] +#[gen_stub_pyclass_enum] +enum PyInputType { + /// + Bool, + /// + F16, + /// + F32, + /// + F64, + /// + Int, + /// + TDim, +} + +impl From for PyInputType { + fn from(input_type: InputType) -> Self { + match input_type { + InputType::Bool => PyInputType::Bool, + InputType::F16 => PyInputType::F16, + InputType::F32 => PyInputType::F32, + InputType::F64 => PyInputType::F64, + InputType::Int => PyInputType::Int, + InputType::TDim => PyInputType::TDim, + } + } +} + +impl From for InputType { + fn from(py_input_type: PyInputType) -> Self { + match py_input_type { + PyInputType::Bool => InputType::Bool, + PyInputType::F16 => InputType::F16, + PyInputType::F32 => InputType::F32, + PyInputType::F64 => InputType::F64, + PyInputType::Int => InputType::Int, + PyInputType::TDim => InputType::TDim, + } + } +} + +impl FromStr for PyInputType { + type Err = String; + fn from_str(s: &str) -> Result { + match s.to_lowercase().as_str() { + "bool" => Ok(PyInputType::Bool), + "f16" => Ok(PyInputType::F16), + "f32" => Ok(PyInputType::F32), + "f64" => Ok(PyInputType::F64), + "int" => Ok(PyInputType::Int), + "tdim" => Ok(PyInputType::TDim), + _ => Err("Invalid value for InputType".to_string()), + } + } +} + /// Converts a field element hex string to big endian /// /// Arguments @@ -322,6 +392,7 @@ impl FromStr for PyCommitments { #[pyfunction(signature = ( felt, ))] +#[gen_stub_pyfunction] fn felt_to_big_endian(felt: PyFelt) -> PyResult { let felt = crate::pfsys::string_to_field::(&felt); Ok(format!("{:?}", felt)) @@ -341,6 +412,7 @@ fn felt_to_big_endian(felt: PyFelt) -> PyResult { #[pyfunction(signature = ( felt, ))] +#[gen_stub_pyfunction] fn felt_to_int(felt: PyFelt) -> PyResult { let felt = crate::pfsys::string_to_field::(&felt); let int_rep = felt_to_integer_rep(felt); @@ -365,6 +437,7 @@ fn felt_to_int(felt: PyFelt) -> PyResult { felt, scale ))] +#[gen_stub_pyfunction] fn felt_to_float(felt: PyFelt, scale: crate::Scale) -> PyResult { let felt = crate::pfsys::string_to_field::(&felt); let int_rep = felt_to_integer_rep(felt); @@ -383,6 +456,9 @@ fn felt_to_float(felt: PyFelt, scale: crate::Scale) -> PyResult { /// scale: float /// The scaling factor used to quantize the float into a field element /// +/// input_type: PyInputType +/// The type of the input +/// /// Returns /// ------- /// str @@ -390,9 +466,12 @@ fn felt_to_float(felt: PyFelt, scale: crate::Scale) -> PyResult { /// #[pyfunction(signature = ( input, - scale + scale, + input_type=PyInputType::F64 ))] -fn float_to_felt(input: f64, scale: crate::Scale) -> PyResult { +#[gen_stub_pyfunction] +fn float_to_felt(mut input: f64, scale: crate::Scale, input_type: PyInputType) -> PyResult { + InputType::roundtrip(&input_type.into(), &mut input); let int_rep = quantize_float(&input, 0.0, scale) .map_err(|_| PyIOError::new_err("Failed to quantize input"))?; let felt = integer_rep_to_felt(int_rep); @@ -414,6 +493,7 @@ fn float_to_felt(input: f64, scale: crate::Scale) -> PyResult { #[pyfunction(signature = ( buffer ))] +#[gen_stub_pyfunction] fn buffer_to_felts(buffer: Vec) -> PyResult> { fn u8_array_to_u128_le(arr: [u8; 16]) -> u128 { let mut n: u128 = 0; @@ -486,6 +566,7 @@ fn buffer_to_felts(buffer: Vec) -> PyResult> { #[pyfunction(signature = ( message, ))] +#[gen_stub_pyfunction] fn poseidon_hash(message: Vec) -> PyResult> { let message: Vec = message .iter() @@ -531,6 +612,7 @@ fn poseidon_hash(message: Vec) -> PyResult> { settings_path=PathBuf::from(DEFAULT_SETTINGS), srs_path=None ))] +#[gen_stub_pyfunction] fn kzg_commit( message: Vec, vk_path: PathBuf, @@ -589,6 +671,7 @@ fn kzg_commit( settings_path=PathBuf::from(DEFAULT_SETTINGS), srs_path=None ))] +#[gen_stub_pyfunction] fn ipa_commit( message: Vec, vk_path: PathBuf, @@ -635,6 +718,7 @@ fn ipa_commit( proof_path=PathBuf::from(DEFAULT_PROOF), witness_path=PathBuf::from(DEFAULT_WITNESS), ))] +#[gen_stub_pyfunction] fn swap_proof_commitments(proof_path: PathBuf, witness_path: PathBuf) -> PyResult<()> { crate::execute::swap_proof_commitments_cmd(proof_path, witness_path) .map_err(|_| PyIOError::new_err("Failed to swap commitments"))?; @@ -664,6 +748,7 @@ fn swap_proof_commitments(proof_path: PathBuf, witness_path: PathBuf) -> PyResul circuit_settings_path=PathBuf::from(DEFAULT_SETTINGS), vk_output_path=PathBuf::from(DEFAULT_VK), ))] +#[gen_stub_pyfunction] fn gen_vk_from_pk_single( path_to_pk: PathBuf, circuit_settings_path: PathBuf, @@ -701,6 +786,7 @@ fn gen_vk_from_pk_single( path_to_pk=PathBuf::from(DEFAULT_PK_AGGREGATED), vk_output_path=PathBuf::from(DEFAULT_VK_AGGREGATED), ))] +#[gen_stub_pyfunction] fn gen_vk_from_pk_aggr(path_to_pk: PathBuf, vk_output_path: PathBuf) -> PyResult { let pk = load_pk::, AggregationCircuit>(path_to_pk, ()) .map_err(|_| PyIOError::new_err("Failed to load pk"))?; @@ -730,6 +816,7 @@ fn gen_vk_from_pk_aggr(path_to_pk: PathBuf, vk_output_path: PathBuf) -> PyResult model = PathBuf::from(DEFAULT_MODEL), py_run_args = None ))] +#[gen_stub_pyfunction] fn table(model: PathBuf, py_run_args: Option) -> PyResult { let run_args: RunArgs = py_run_args.unwrap_or_else(PyRunArgs::new).into(); let mut reader = File::open(model).map_err(|_| PyIOError::new_err("Failed to open model"))?; @@ -755,6 +842,7 @@ fn table(model: PathBuf, py_run_args: Option) -> PyResult { srs_path, logrows, ))] +#[gen_stub_pyfunction] fn gen_srs(srs_path: PathBuf, logrows: usize) -> PyResult<()> { let params = ezkl_gen_srs::>(logrows as u32); save_params::>(&srs_path, ¶ms)?; @@ -787,6 +875,7 @@ fn gen_srs(srs_path: PathBuf, logrows: usize) -> PyResult<()> { srs_path=None, commitment=None, ))] +#[gen_stub_pyfunction] fn get_srs( py: Python, settings_path: Option, @@ -799,7 +888,7 @@ fn get_srs( None => None, }; - pyo3_asyncio::tokio::future_into_py(py, async move { + pyo3_async_runtimes::tokio::future_into_py(py, async move { crate::execute::get_srs_cmd(srs_path, settings_path, logrows, commitment) .await .map_err(|e| { @@ -833,6 +922,7 @@ fn get_srs( output=PathBuf::from(DEFAULT_SETTINGS), py_run_args = None, ))] +#[gen_stub_pyfunction] fn gen_settings( model: PathBuf, output: PathBuf, @@ -888,6 +978,7 @@ fn gen_settings( scale_rebase_multiplier = DEFAULT_SCALE_REBASE_MULTIPLIERS.split(",").map(|x| x.parse().unwrap()).collect(), max_logrows = None, ))] +#[gen_stub_pyfunction] fn calibrate_settings( py: Python, data: PathBuf, @@ -899,7 +990,7 @@ fn calibrate_settings( scale_rebase_multiplier: Vec, max_logrows: Option, ) -> PyResult> { - pyo3_asyncio::tokio::future_into_py(py, async move { + pyo3_async_runtimes::tokio::future_into_py(py, async move { crate::execute::calibrate( model, data, @@ -951,6 +1042,7 @@ fn calibrate_settings( vk_path=None, srs_path=None, ))] +#[gen_stub_pyfunction] fn gen_witness( py: Python, data: PathBuf, @@ -959,7 +1051,7 @@ fn gen_witness( vk_path: Option, srs_path: Option, ) -> PyResult> { - pyo3_asyncio::tokio::future_into_py(py, async move { + pyo3_async_runtimes::tokio::future_into_py(py, async move { let output = crate::execute::gen_witness(model, data, output, vk_path, srs_path) .await .map_err(|e| { @@ -988,6 +1080,7 @@ fn gen_witness( witness=PathBuf::from(DEFAULT_WITNESS), model=PathBuf::from(DEFAULT_COMPILED_CIRCUIT), ))] +#[gen_stub_pyfunction] fn mock(witness: PathBuf, model: PathBuf) -> PyResult { crate::execute::mock(model, witness).map_err(|e| { let err_str = format!("Failed to run mock: {}", e); @@ -1018,6 +1111,7 @@ fn mock(witness: PathBuf, model: PathBuf) -> PyResult { logrows=DEFAULT_AGGREGATED_LOGROWS.parse().unwrap(), split_proofs = false, ))] +#[gen_stub_pyfunction] fn mock_aggregate( aggregation_snarks: Vec, logrows: u32, @@ -1065,6 +1159,7 @@ fn mock_aggregate( witness_path = None, disable_selector_compression=DEFAULT_DISABLE_SELECTOR_COMPRESSION.parse().unwrap(), ))] +#[gen_stub_pyfunction] fn setup( model: PathBuf, vk_path: PathBuf, @@ -1123,6 +1218,7 @@ fn setup( proof_type=ProofType::default(), srs_path=None, ))] +#[gen_stub_pyfunction] fn prove( witness: PathBuf, model: PathBuf, @@ -1178,6 +1274,7 @@ fn prove( srs_path=None, reduced_srs=DEFAULT_USE_REDUCED_SRS_FOR_VERIFICATION.parse::().unwrap(), ))] +#[gen_stub_pyfunction] fn verify( proof_path: PathBuf, settings_path: PathBuf, @@ -1237,6 +1334,7 @@ fn verify( disable_selector_compression=DEFAULT_DISABLE_SELECTOR_COMPRESSION.parse().unwrap(), commitment=DEFAULT_COMMITMENT.parse().unwrap(), ))] +#[gen_stub_pyfunction] fn setup_aggregate( sample_snarks: Vec, vk_path: PathBuf, @@ -1287,6 +1385,7 @@ fn setup_aggregate( compiled_circuit=PathBuf::from(DEFAULT_COMPILED_CIRCUIT), settings_path=PathBuf::from(DEFAULT_SETTINGS), ))] +#[gen_stub_pyfunction] fn compile_circuit( model: PathBuf, compiled_circuit: PathBuf, @@ -1346,6 +1445,7 @@ fn compile_circuit( srs_path=None, commitment=DEFAULT_COMMITMENT.parse().unwrap(), ))] +#[gen_stub_pyfunction] fn aggregate( aggregation_snarks: Vec, proof_path: PathBuf, @@ -1411,6 +1511,7 @@ fn aggregate( reduced_srs=DEFAULT_USE_REDUCED_SRS_FOR_VERIFICATION.parse().unwrap(), srs_path=None, ))] +#[gen_stub_pyfunction] fn verify_aggr( proof_path: PathBuf, vk_path: PathBuf, @@ -1458,6 +1559,7 @@ fn verify_aggr( calldata=PathBuf::from(DEFAULT_CALLDATA), addr_vk=None, ))] +#[gen_stub_pyfunction] fn encode_evm_calldata<'a>( proof: PathBuf, calldata: PathBuf, @@ -1510,6 +1612,7 @@ fn encode_evm_calldata<'a>( srs_path=None, reusable = DEFAULT_RENDER_REUSABLE.parse().unwrap(), ))] +#[gen_stub_pyfunction] fn create_evm_verifier( py: Python, vk_path: PathBuf, @@ -1519,7 +1622,7 @@ fn create_evm_verifier( srs_path: Option, reusable: bool, ) -> PyResult> { - pyo3_asyncio::tokio::future_into_py(py, async move { + pyo3_async_runtimes::tokio::future_into_py(py, async move { crate::execute::create_evm_verifier( vk_path, srs_path, @@ -1569,6 +1672,7 @@ fn create_evm_verifier( abi_path=PathBuf::from(DEFAULT_VERIFIER_ABI), srs_path=None ))] +#[gen_stub_pyfunction] fn create_evm_vka( py: Python, vk_path: PathBuf, @@ -1577,7 +1681,7 @@ fn create_evm_vka( abi_path: PathBuf, srs_path: Option, ) -> PyResult> { - pyo3_asyncio::tokio::future_into_py(py, async move { + pyo3_async_runtimes::tokio::future_into_py(py, async move { crate::execute::create_evm_vka(vk_path, srs_path, settings_path, sol_code_path, abi_path) .await .map_err(|e| { @@ -1616,6 +1720,7 @@ fn create_evm_vka( abi_path=PathBuf::from(DEFAULT_VERIFIER_DA_ABI), witness_path=None, ))] +#[gen_stub_pyfunction] fn create_evm_data_attestation( py: Python, input_data: PathBuf, @@ -1624,7 +1729,7 @@ fn create_evm_data_attestation( abi_path: PathBuf, witness_path: Option, ) -> PyResult> { - pyo3_asyncio::tokio::future_into_py(py, async move { + pyo3_async_runtimes::tokio::future_into_py(py, async move { crate::execute::create_evm_data_attestation( settings_path, sol_code_path, @@ -1676,6 +1781,7 @@ fn create_evm_data_attestation( output_source, rpc_url=None, ))] +#[gen_stub_pyfunction] fn setup_test_evm_witness( py: Python, data_path: PathBuf, @@ -1685,7 +1791,7 @@ fn setup_test_evm_witness( output_source: PyTestDataSource, rpc_url: Option, ) -> PyResult> { - pyo3_asyncio::tokio::future_into_py(py, async move { + pyo3_async_runtimes::tokio::future_into_py(py, async move { crate::execute::setup_test_evm_witness( data_path, compiled_circuit_path, @@ -1713,6 +1819,7 @@ fn setup_test_evm_witness( optimizer_runs=DEFAULT_OPTIMIZER_RUNS.parse().unwrap(), private_key=None, ))] +#[gen_stub_pyfunction] fn deploy_evm( py: Python, addr_path: PathBuf, @@ -1722,7 +1829,7 @@ fn deploy_evm( optimizer_runs: usize, private_key: Option, ) -> PyResult> { - pyo3_asyncio::tokio::future_into_py(py, async move { + pyo3_async_runtimes::tokio::future_into_py(py, async move { crate::execute::deploy_evm( sol_code_path, rpc_url, @@ -1751,6 +1858,7 @@ fn deploy_evm( optimizer_runs=DEFAULT_OPTIMIZER_RUNS.parse().unwrap(), private_key=None ))] +#[gen_stub_pyfunction] fn deploy_da_evm( py: Python, addr_path: PathBuf, @@ -1761,7 +1869,7 @@ fn deploy_da_evm( optimizer_runs: usize, private_key: Option, ) -> PyResult> { - pyo3_asyncio::tokio::future_into_py(py, async move { + pyo3_async_runtimes::tokio::future_into_py(py, async move { crate::execute::deploy_da_evm( input_data, settings_path, @@ -1809,6 +1917,7 @@ fn deploy_da_evm( addr_da = None, addr_vk = None, ))] +#[gen_stub_pyfunction] fn verify_evm<'a>( py: Python<'a>, addr_verifier: &'a str, @@ -1831,7 +1940,7 @@ fn verify_evm<'a>( None }; - pyo3_asyncio::tokio::future_into_py(py, async move { + pyo3_async_runtimes::tokio::future_into_py(py, async move { crate::execute::verify_evm(proof_path, addr_verifier, rpc_url, addr_da, addr_vk) .await .map_err(|e| { @@ -1881,6 +1990,7 @@ fn verify_evm<'a>( srs_path=None, reusable = DEFAULT_RENDER_REUSABLE.parse().unwrap(), ))] +#[gen_stub_pyfunction] fn create_evm_verifier_aggr( py: Python, aggregation_settings: Vec, @@ -1891,7 +2001,7 @@ fn create_evm_verifier_aggr( srs_path: Option, reusable: bool, ) -> PyResult> { - pyo3_asyncio::tokio::future_into_py(py, async move { + pyo3_async_runtimes::tokio::future_into_py(py, async move { crate::execute::create_evm_aggregate_verifier( vk_path, srs_path, @@ -1911,15 +2021,19 @@ fn create_evm_verifier_aggr( }) } +// Define a function to gather stub information. +define_stub_info_gatherer!(stub_info); + // Python Module #[pymodule] -fn ezkl(_py: Python<'_>, m: &PyModule) -> PyResult<()> { +fn ezkl(m: &Bound<'_, PyModule>) -> PyResult<()> { pyo3_log::init(); m.add_class::()?; m.add_class::()?; m.add_class::()?; m.add_class::()?; m.add_class::()?; + m.add_class::()?; m.add("__version__", env!("CARGO_PKG_VERSION"))?; m.add_function(wrap_pyfunction!(felt_to_big_endian, m)?)?; m.add_function(wrap_pyfunction!(felt_to_int, m)?)?; @@ -1958,3 +2072,48 @@ fn ezkl(_py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_function(wrap_pyfunction!(encode_evm_calldata, m)?)?; Ok(()) } + +impl pyo3_stub_gen::PyStubType for CalibrationTarget { + fn type_output() -> TypeInfo { + TypeInfo { + name: "str".to_string(), + import: HashSet::new(), + } + } +} + +impl pyo3_stub_gen::PyStubType for ProofType { + fn type_output() -> TypeInfo { + TypeInfo { + name: "str".to_string(), + import: HashSet::new(), + } + } +} + +impl pyo3_stub_gen::PyStubType for TranscriptType { + fn type_output() -> TypeInfo { + TypeInfo { + name: "str".to_string(), + import: HashSet::new(), + } + } +} + +impl pyo3_stub_gen::PyStubType for CheckMode { + fn type_output() -> TypeInfo { + TypeInfo { + name: "str".to_string(), + import: HashSet::new(), + } + } +} + +impl pyo3_stub_gen::PyStubType for ContractType { + fn type_output() -> TypeInfo { + TypeInfo { + name: "str".to_string(), + import: HashSet::new(), + } + } +} diff --git a/src/bindings/wasm.rs b/src/bindings/wasm.rs index 3adc41843..bcec19837 100644 --- a/src/bindings/wasm.rs +++ b/src/bindings/wasm.rs @@ -22,6 +22,7 @@ use halo2curves::{ bn256::{Bn256, Fr, G1Affine}, ff::PrimeField, }; +use std::str::FromStr; use wasm_bindgen::prelude::*; use wasm_bindgen_console_logger::DEFAULT_LOGGER; @@ -113,9 +114,15 @@ pub fn feltToFloat( #[wasm_bindgen] #[allow(non_snake_case)] pub fn floatToFelt( - input: f64, + mut input: f64, scale: crate::Scale, + input_type: &str, ) -> Result>, JsError> { + crate::circuit::InputType::roundtrip( + &crate::circuit::InputType::from_str(input_type) + .map_err(|e| JsError::new(&format!("{}", e)))?, + &mut input, + ); let int_rep = quantize_float(&input, 0.0, scale).map_err(|e| JsError::new(&format!("{}", e)))?; let felt = integer_rep_to_felt(int_rep); diff --git a/src/circuit/ops/chip.rs b/src/circuit/ops/chip.rs index 446ff069e..e208ace03 100644 --- a/src/circuit/ops/chip.rs +++ b/src/circuit/ops/chip.rs @@ -8,10 +8,9 @@ use halo2_proofs::{ use log::debug; #[cfg(feature = "python-bindings")] use pyo3::{ - conversion::{FromPyObject, PyTryFrom}, + conversion::{FromPyObject, IntoPy}, exceptions::PyValueError, prelude::*, - types::PyString, }; use serde::{Deserialize, Serialize}; #[cfg(all(feature = "ezkl", not(target_arch = "wasm32")))] @@ -139,10 +138,9 @@ impl IntoPy for CheckMode { #[cfg(feature = "python-bindings")] /// Obtains CheckMode from PyObject (Required for CheckMode to be compatible with Python) impl<'source> FromPyObject<'source> for CheckMode { - fn extract(ob: &'source PyAny) -> PyResult { - let trystr = ::try_from(ob)?; - let strval = trystr.to_string(); - match strval.to_lowercase().as_str() { + fn extract_bound(ob: &pyo3::Bound<'source, pyo3::PyAny>) -> PyResult { + let trystr = String::extract_bound(ob)?; + match trystr.to_lowercase().as_str() { "safe" => Ok(CheckMode::SAFE), "unsafe" => Ok(CheckMode::UNSAFE), _ => Err(PyValueError::new_err("Invalid value for CheckMode")), @@ -161,8 +159,8 @@ impl IntoPy for Tolerance { #[cfg(feature = "python-bindings")] /// Obtains Tolerance from PyObject (Required for Tolerance to be compatible with Python) impl<'source> FromPyObject<'source> for Tolerance { - fn extract(ob: &'source PyAny) -> PyResult { - if let Ok((val, scale)) = ob.extract::<(f32, f32)>() { + fn extract_bound(ob: &pyo3::Bound<'source, pyo3::PyAny>) -> PyResult { + if let Ok((val, scale)) = <(f32, f32)>::extract_bound(ob) { Ok(Tolerance { val, scale: utils::F32(scale), diff --git a/src/circuit/ops/errors.rs b/src/circuit/ops/errors.rs index cb488ca6b..97e6da8f3 100644 --- a/src/circuit/ops/errors.rs +++ b/src/circuit/ops/errors.rs @@ -97,4 +97,7 @@ pub enum CircuitError { /// Invalid scale #[error("negative scale for an op that requires positive inputs {0}")] NegativeScale(String), + #[error("invalid input type {0}")] + /// Invalid input type + InvalidInputType(String), } diff --git a/src/circuit/ops/mod.rs b/src/circuit/ops/mod.rs index 552a782fc..1ac8ba91c 100644 --- a/src/circuit/ops/mod.rs +++ b/src/circuit/ops/mod.rs @@ -105,7 +105,10 @@ impl InputType { } /// - pub fn roundtrip(&self, input: &mut T) { + pub fn roundtrip( + &self, + input: &mut T, + ) { match self { InputType::Bool => { let boolean_input = input.clone().to_i64().unwrap(); @@ -118,7 +121,7 @@ impl InputType { *input = T::from_f32(f32_input).unwrap(); } InputType::F32 => { - let f32_input = input.clone().to_f32().unwrap(); + let f32_input: f32 = input.clone().to_f32().unwrap(); *input = T::from_f32(f32_input).unwrap(); } InputType::F64 => { @@ -133,6 +136,22 @@ impl InputType { } } +impl std::str::FromStr for InputType { + type Err = CircuitError; + + fn from_str(s: &str) -> Result { + match s { + "bool" => Ok(InputType::Bool), + "f16" => Ok(InputType::F16), + "f32" => Ok(InputType::F32), + "f64" => Ok(InputType::F64), + "int" => Ok(InputType::Int), + "tdim" => Ok(InputType::TDim), + e => Err(CircuitError::InvalidInputType(e.to_string())), + } + } +} + /// #[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)] pub struct Input { diff --git a/src/circuit/ops/region.rs b/src/circuit/ops/region.rs index 9c92c8901..d6fed4239 100644 --- a/src/circuit/ops/region.rs +++ b/src/circuit/ops/region.rs @@ -211,7 +211,7 @@ impl<'a, F: PrimeField + TensorType + PartialOrd + std::hash::Hash> RegionCtx<'a self.min_lookup_inputs().to_string().green(), self.max_range_size().to_string().green(), self.dynamic_lookup_col_coord().to_string().green(), - self.shuffle_col_coord().to_string().green(), + self.shuffle_col_coord().to_string().green(), self.max_dynamic_input_len().to_string().green() ); } @@ -474,7 +474,7 @@ impl<'a, F: PrimeField + TensorType + PartialOrd + std::hash::Hash> RegionCtx<'a Ok(()) } - /// Update the max and min forcefully + /// Update the max and min forcefully pub fn update_max_min_lookup_inputs_force( &mut self, min: IntegerRep, @@ -611,7 +611,6 @@ impl<'a, F: PrimeField + TensorType + PartialOrd + std::hash::Hash> RegionCtx<'a var: &VarTensor, values: &ValTensor, ) -> Result<(ValTensor, usize), CircuitError> { - self.update_max_dynamic_input_len(values.len()); if let Some(region) = &self.region { diff --git a/src/commands.rs b/src/commands.rs index 03f57d501..9ca203f11 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -2,12 +2,7 @@ use alloy::primitives::Address as H160; use clap::{Command, Parser, Subcommand}; use clap_complete::{generate, Generator, Shell}; #[cfg(feature = "python-bindings")] -use pyo3::{ - conversion::{FromPyObject, PyTryFrom}, - exceptions::PyValueError, - prelude::*, - types::PyString, -}; +use pyo3::{conversion::FromPyObject, exceptions::PyValueError, prelude::*}; use serde::{Deserialize, Serialize}; use std::path::PathBuf; use std::str::FromStr; @@ -109,8 +104,8 @@ impl IntoPy for TranscriptType { #[cfg(feature = "python-bindings")] /// Obtains TranscriptType from PyObject (Required for TranscriptType to be compatible with Python) impl<'source> FromPyObject<'source> for TranscriptType { - fn extract(ob: &'source PyAny) -> PyResult { - let trystr = ::try_from(ob)?; + fn extract_bound(ob: &pyo3::Bound<'source, pyo3::PyAny>) -> PyResult { + let trystr = String::extract_bound(ob)?; let strval = trystr.to_string(); match strval.to_lowercase().as_str() { "poseidon" => Ok(TranscriptType::Poseidon), @@ -196,9 +191,7 @@ pub enum ContractType { impl Default for ContractType { fn default() -> Self { - ContractType::Verifier { - reusable: false, - } + ContractType::Verifier { reusable: false } } } @@ -210,10 +203,8 @@ impl std::fmt::Display for ContractType { match self { ContractType::Verifier { reusable: true } => { "verifier/reusable".to_string() - }, - ContractType::Verifier { - reusable: false, - } => "verifier".to_string(), + } + ContractType::Verifier { reusable: false } => "verifier".to_string(), ContractType::VerifyingKeyArtifact => "vka".to_string(), } ) @@ -241,7 +232,6 @@ impl From<&str> for ContractType { } } - #[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq, PartialOrd)] /// wrapper for H160 to make it easy to parse into flag vals pub struct H160Flag { @@ -287,9 +277,8 @@ impl IntoPy for CalibrationTarget { #[cfg(feature = "python-bindings")] /// Obtains CalibrationTarget from PyObject (Required for CalibrationTarget to be compatible with Python) impl<'source> FromPyObject<'source> for CalibrationTarget { - fn extract(ob: &'source PyAny) -> PyResult { - let trystr = ::try_from(ob)?; - let strval = trystr.to_string(); + fn extract_bound(ob: &pyo3::Bound<'source, pyo3::PyAny>) -> PyResult { + let strval = String::extract_bound(ob)?; match strval.to_lowercase().as_str() { "resources" => Ok(CalibrationTarget::Resources { col_overflow: false, @@ -306,12 +295,8 @@ impl<'source> FromPyObject<'source> for CalibrationTarget { impl IntoPy for ContractType { fn into_py(self, py: Python) -> PyObject { match self { - ContractType::Verifier { reusable: true } => { - "verifier/reusable".to_object(py) - } - ContractType::Verifier { - reusable: false, - } => "verifier".to_object(py), + ContractType::Verifier { reusable: true } => "verifier/reusable".to_object(py), + ContractType::Verifier { reusable: false } => "verifier".to_object(py), ContractType::VerifyingKeyArtifact => "vka".to_object(py), } } @@ -320,13 +305,10 @@ impl IntoPy for ContractType { #[cfg(feature = "python-bindings")] /// Obtains ContractType from PyObject (Required for ContractType to be compatible with Python) impl<'source> FromPyObject<'source> for ContractType { - fn extract(ob: &'source PyAny) -> PyResult { - let trystr = ::try_from(ob)?; - let strval = trystr.to_string(); + fn extract_bound(ob: &pyo3::Bound<'source, pyo3::PyAny>) -> PyResult { + let strval = String::extract_bound(ob)?; match strval.to_lowercase().as_str() { - "verifier" => Ok(ContractType::Verifier { - reusable: false, - }), + "verifier" => Ok(ContractType::Verifier { reusable: false }), "verifier/reusable" => Ok(ContractType::Verifier { reusable: true }), "vka" => Ok(ContractType::VerifyingKeyArtifact), _ => Err(PyValueError::new_err("Invalid value for ContractType")), @@ -341,45 +323,45 @@ pub fn get_styles() -> clap::builder::Styles { clap::builder::styling::Style::new() .bold() .underline() - .fg_color(Some(clap::builder::styling::Color::Ansi(clap::builder::styling::AnsiColor::Cyan))), + .fg_color(Some(clap::builder::styling::Color::Ansi( + clap::builder::styling::AnsiColor::Cyan, + ))), ) .header( clap::builder::styling::Style::new() .bold() .underline() - .fg_color(Some(clap::builder::styling::Color::Ansi(clap::builder::styling::AnsiColor::Cyan))), - ) - .literal( - clap::builder::styling::Style::new().fg_color(Some(clap::builder::styling::Color::Ansi(clap::builder::styling::AnsiColor::Magenta))), - ) - .invalid( - clap::builder::styling::Style::new() - .bold() - .fg_color(Some(clap::builder::styling::Color::Ansi(clap::builder::styling::AnsiColor::Red))), - ) - .error( - clap::builder::styling::Style::new() - .bold() - .fg_color(Some(clap::builder::styling::Color::Ansi(clap::builder::styling::AnsiColor::Red))), + .fg_color(Some(clap::builder::styling::Color::Ansi( + clap::builder::styling::AnsiColor::Cyan, + ))), ) + .literal(clap::builder::styling::Style::new().fg_color(Some( + clap::builder::styling::Color::Ansi(clap::builder::styling::AnsiColor::Magenta), + ))) + .invalid(clap::builder::styling::Style::new().bold().fg_color(Some( + clap::builder::styling::Color::Ansi(clap::builder::styling::AnsiColor::Red), + ))) + .error(clap::builder::styling::Style::new().bold().fg_color(Some( + clap::builder::styling::Color::Ansi(clap::builder::styling::AnsiColor::Red), + ))) .valid( clap::builder::styling::Style::new() .bold() .underline() - .fg_color(Some(clap::builder::styling::Color::Ansi(clap::builder::styling::AnsiColor::Green))), - ) - .placeholder( - clap::builder::styling::Style::new().fg_color(Some(clap::builder::styling::Color::Ansi(clap::builder::styling::AnsiColor::White))), + .fg_color(Some(clap::builder::styling::Color::Ansi( + clap::builder::styling::AnsiColor::Green, + ))), ) + .placeholder(clap::builder::styling::Style::new().fg_color(Some( + clap::builder::styling::Color::Ansi(clap::builder::styling::AnsiColor::White), + ))) } - /// Print completions for the given generator pub fn print_completions(gen: G, cmd: &mut Command) { generate(gen, cmd, cmd.get_name().to_string(), &mut std::io::stdout()); } - #[allow(missing_docs)] #[derive(Parser, Debug, Clone)] #[command(author, about, long_about = None)] @@ -393,7 +375,6 @@ pub struct Cli { pub command: Option, } - #[allow(missing_docs)] #[derive(Debug, Subcommand, Clone, Deserialize, Serialize, PartialEq, PartialOrd, ToSubcommand)] pub enum Commands { @@ -443,7 +424,7 @@ pub enum Commands { }, /// Calibrates the proving scale, lookup bits and logrows from a circuit settings file. - CalibrateSettings { + CalibrateSettings { /// The path to the .json calibration data file. #[arg(short = 'D', long, default_value = DEFAULT_CALIBRATION_FILE, value_hint = clap::ValueHint::FilePath)] data: Option, @@ -490,7 +471,7 @@ pub enum Commands { commitment: Option, }, - /// Gets an SRS from a circuit settings file. + /// Gets an SRS from a circuit settings file. #[command(name = "get-srs")] GetSrs { /// The path to output the desired srs file, if set to None will save to ~/.ezkl/srs @@ -575,7 +556,7 @@ pub enum Commands { require_equals = true, num_args = 0..=1, default_value_t = TranscriptType::default(), - value_enum, + value_enum, value_hint = clap::ValueHint::Other )] transcript: TranscriptType, @@ -625,7 +606,7 @@ pub enum Commands { #[arg(long, default_value = DEFAULT_DISABLE_SELECTOR_COMPRESSION, action = clap::ArgAction::SetTrue)] disable_selector_compression: Option, }, - /// Deploys a test contact that the data attester reads from and creates a data attestation formatted input.json file that contains call data information + /// Deploys a test contact that the data attester reads from and creates a data attestation formatted input.json file that contains call data information #[command(arg_required_else_help = true)] SetupTestEvmData { /// The path to the .json data file, which should include both the network input (possibly private) and the network output (public input to the proof) @@ -649,7 +630,7 @@ pub enum Commands { #[arg(long, default_value = "on-chain", value_hint = clap::ValueHint::Other)] output_source: TestDataSource, }, - /// The Data Attestation Verifier contract stores the account calls to fetch data to feed into ezkl. This call data can be updated by an admin account. This tests that admin account is able to update this call data. + /// The Data Attestation Verifier contract stores the account calls to fetch data to feed into ezkl. This call data can be updated by an admin account. This tests that admin account is able to update this call data. #[command(arg_required_else_help = true)] TestUpdateAccountCalls { /// The path to the verifier contract's address @@ -662,7 +643,7 @@ pub enum Commands { #[arg(short = 'U', long, value_hint = clap::ValueHint::Url)] rpc_url: Option, }, - /// Swaps the positions in the transcript that correspond to commitments + /// Swaps the positions in the transcript that correspond to commitments SwapProofCommitments { /// The path to the proof file #[arg(short = 'P', long, default_value = DEFAULT_PROOF, value_hint = clap::ValueHint::FilePath)] @@ -672,7 +653,7 @@ pub enum Commands { witness_path: Option, }, - /// Loads model, data, and creates proof + /// Loads model, data, and creates proof Prove { /// The path to the .json witness file (generated using the gen-witness command) #[arg(short = 'W', long, default_value = DEFAULT_WITNESS, value_hint = clap::ValueHint::FilePath)] @@ -694,7 +675,7 @@ pub enum Commands { require_equals = true, num_args = 0..=1, default_value_t = ProofType::Single, - value_enum, + value_enum, value_hint = clap::ValueHint::Other )] proof_type: ProofType, @@ -702,7 +683,7 @@ pub enum Commands { #[arg(long, default_value = DEFAULT_CHECKMODE, value_hint = clap::ValueHint::Other)] check_mode: Option, }, - /// Encodes a proof into evm calldata + /// Encodes a proof into evm calldata #[command(name = "encode-evm-calldata")] EncodeEvmCalldata { /// The path to the proof file (generated using the prove command) @@ -715,7 +696,7 @@ pub enum Commands { #[arg(long, value_hint = clap::ValueHint::Other)] addr_vk: Option, }, - /// Creates an Evm verifier for a single proof + /// Creates an Evm verifier for a single proof #[command(name = "create-evm-verifier")] CreateEvmVerifier { /// The path to SRS, if None will use ~/.ezkl/srs/kzg{logrows}.srs @@ -737,7 +718,7 @@ pub enum Commands { #[arg(long, default_value = DEFAULT_RENDER_REUSABLE, action = clap::ArgAction::SetTrue)] reusable: Option, }, - /// Creates an Evm verifier artifact for a single proof to be used by the reusable verifier + /// Creates an Evm verifier artifact for a single proof to be used by the reusable verifier #[command(name = "create-evm-vka")] CreateEvmVKArtifact { /// The path to SRS, if None will use ~/.ezkl/srs/kzg{logrows}.srs @@ -756,7 +737,7 @@ pub enum Commands { #[arg(long, default_value = DEFAULT_VK_ABI, value_hint = clap::ValueHint::FilePath)] abi_path: Option, }, - /// Creates an Evm verifier that attests to on-chain inputs for a single proof + /// Creates an Evm verifier that attests to on-chain inputs for a single proof #[command(name = "create-evm-da")] CreateEvmDataAttestation { /// The path to load circuit settings .json file from (generated using the gen-settings command) @@ -780,7 +761,7 @@ pub enum Commands { witness: Option, }, - /// Creates an Evm verifier for an aggregate proof + /// Creates an Evm verifier for an aggregate proof #[command(name = "create-evm-verifier-aggr")] CreateEvmVerifierAggr { /// The path to SRS, if None will use ~/.ezkl/srs/kzg{logrows}.srs @@ -844,7 +825,7 @@ pub enum Commands { #[arg(long, default_value = DEFAULT_COMMITMENT, value_hint = clap::ValueHint::Other)] commitment: Option, }, - /// Deploys an evm contract (verifier, reusable verifier, or vk artifact) that is generated by ezkl + /// Deploys an evm contract (verifier, reusable verifier, or vk artifact) that is generated by ezkl DeployEvm { /// The path to the Solidity code (generated using the create-evm-verifier command) #[arg(long, default_value = DEFAULT_SOL_CODE, value_hint = clap::ValueHint::FilePath)] @@ -865,7 +846,7 @@ pub enum Commands { #[arg(long = "contract-type", short = 'C', default_value = DEFAULT_CONTRACT_DEPLOYMENT_TYPE, value_hint = clap::ValueHint::Other)] contract: ContractType, }, - /// Deploys an evm verifier that allows for data attestation + /// Deploys an evm verifier that allows for data attestation #[command(name = "deploy-evm-da")] DeployEvmDataAttestation { /// The path to the .json data file, which should include both the network input (possibly private) and the network output (public input to the proof) @@ -890,7 +871,7 @@ pub enum Commands { #[arg(short = 'P', long, value_hint = clap::ValueHint::Other)] private_key: Option, }, - /// Verifies a proof using a local Evm executor, returning accept or reject + /// Verifies a proof using a local Evm executor, returning accept or reject #[command(name = "verify-evm")] VerifyEvm { /// The path to the proof file (generated using the prove command) @@ -918,7 +899,6 @@ pub enum Commands { }, } - impl Commands { /// Converts the commands to a json string pub fn as_json(&self) -> String { @@ -929,4 +909,4 @@ impl Commands { pub fn from_json(json: &str) -> Self { serde_json::from_str(json).unwrap() } -} \ No newline at end of file +} diff --git a/src/graph/input.rs b/src/graph/input.rs index 7a7dda3b6..324f23d38 100644 --- a/src/graph/input.rs +++ b/src/graph/input.rs @@ -712,7 +712,8 @@ impl ToPyObject for DataSource { DataSource::OnChain(source) => { let dict = PyDict::new(py); dict.set_item("rpc_url", &source.rpc).unwrap(); - dict.set_item("calls_to_accounts", &source.calls).unwrap(); + dict.set_item("calls_to_accounts", &source.calls.to_object(py)) + .unwrap(); dict.to_object(py) } DataSource::DB(source) => { diff --git a/src/graph/mod.rs b/src/graph/mod.rs index 931f245e7..b5f52f569 100644 --- a/src/graph/mod.rs +++ b/src/graph/mod.rs @@ -60,7 +60,10 @@ use pyo3::prelude::*; #[cfg(feature = "python-bindings")] use pyo3::types::PyDict; #[cfg(feature = "python-bindings")] +use pyo3::types::PyDictMethods; +#[cfg(feature = "python-bindings")] use pyo3::ToPyObject; + use serde::{Deserialize, Serialize}; use std::ops::Deref; pub use utilities::*; @@ -343,10 +346,10 @@ impl ToPyObject for GraphWitness { if let Some(processed_inputs) = &self.processed_inputs { //poseidon_hash if let Some(processed_inputs_poseidon_hash) = &processed_inputs.poseidon_hash { - insert_poseidon_hash_pydict(dict_inputs, processed_inputs_poseidon_hash).unwrap(); + insert_poseidon_hash_pydict(&dict_inputs, processed_inputs_poseidon_hash).unwrap(); } if let Some(processed_inputs_polycommit) = &processed_inputs.polycommit { - insert_polycommit_pydict(dict_inputs, processed_inputs_polycommit).unwrap(); + insert_polycommit_pydict(&dict_inputs, processed_inputs_polycommit).unwrap(); } dict.set_item("processed_inputs", dict_inputs).unwrap(); @@ -354,10 +357,10 @@ impl ToPyObject for GraphWitness { if let Some(processed_params) = &self.processed_params { if let Some(processed_params_poseidon_hash) = &processed_params.poseidon_hash { - insert_poseidon_hash_pydict(dict_params, processed_params_poseidon_hash).unwrap(); + insert_poseidon_hash_pydict(&dict_params, processed_params_poseidon_hash).unwrap(); } if let Some(processed_params_polycommit) = &processed_params.polycommit { - insert_polycommit_pydict(dict_inputs, processed_params_polycommit).unwrap(); + insert_polycommit_pydict(&dict_params, processed_params_polycommit).unwrap(); } dict.set_item("processed_params", dict_params).unwrap(); @@ -365,10 +368,11 @@ impl ToPyObject for GraphWitness { if let Some(processed_outputs) = &self.processed_outputs { if let Some(processed_outputs_poseidon_hash) = &processed_outputs.poseidon_hash { - insert_poseidon_hash_pydict(dict_outputs, processed_outputs_poseidon_hash).unwrap(); + insert_poseidon_hash_pydict(&dict_outputs, processed_outputs_poseidon_hash) + .unwrap(); } if let Some(processed_outputs_polycommit) = &processed_outputs.polycommit { - insert_polycommit_pydict(dict_inputs, processed_outputs_polycommit).unwrap(); + insert_polycommit_pydict(&dict_outputs, processed_outputs_polycommit).unwrap(); } dict.set_item("processed_outputs", dict_outputs).unwrap(); @@ -379,7 +383,10 @@ impl ToPyObject for GraphWitness { } #[cfg(feature = "python-bindings")] -fn insert_poseidon_hash_pydict(pydict: &PyDict, poseidon_hash: &Vec) -> Result<(), PyErr> { +fn insert_poseidon_hash_pydict( + pydict: &Bound<'_, PyDict>, + poseidon_hash: &Vec, +) -> Result<(), PyErr> { let poseidon_hash: Vec = poseidon_hash.iter().map(field_to_string).collect(); pydict.set_item("poseidon_hash", poseidon_hash)?; @@ -387,7 +394,10 @@ fn insert_poseidon_hash_pydict(pydict: &PyDict, poseidon_hash: &Vec) -> Resu } #[cfg(feature = "python-bindings")] -fn insert_polycommit_pydict(pydict: &PyDict, commits: &Vec>) -> Result<(), PyErr> { +fn insert_polycommit_pydict( + pydict: &Bound<'_, PyDict>, + commits: &Vec>, +) -> Result<(), PyErr> { use crate::bindings::python::PyG1Affine; let poseidon_hash: Vec> = commits .iter() diff --git a/src/graph/vars.rs b/src/graph/vars.rs index 595fbaf5f..565719cdb 100644 --- a/src/graph/vars.rs +++ b/src/graph/vars.rs @@ -9,8 +9,7 @@ use itertools::Itertools; use log::debug; #[cfg(feature = "python-bindings")] use pyo3::{ - exceptions::PyValueError, types::PyString, FromPyObject, IntoPy, PyAny, PyObject, PyResult, - PyTryFrom, Python, ToPyObject, + exceptions::PyValueError, FromPyObject, IntoPy, PyObject, PyResult, Python, ToPyObject, }; use serde::{Deserialize, Serialize}; @@ -137,10 +136,8 @@ impl IntoPy for Visibility { #[cfg(feature = "python-bindings")] /// Obtains Visibility from PyObject (Required for Visibility to be compatible with Python) impl<'source> FromPyObject<'source> for Visibility { - fn extract(ob: &'source PyAny) -> PyResult { - let trystr = ::try_from(ob)?; - let strval = trystr.to_string(); - + fn extract_bound(ob: &pyo3::Bound<'source, pyo3::PyAny>) -> PyResult { + let strval = String::extract_bound(ob)?; let strval = strval.as_str(); if strval.contains("hashed/private") { diff --git a/src/pfsys/mod.rs b/src/pfsys/mod.rs index 017058c0f..d4a8c5fea 100644 --- a/src/pfsys/mod.rs +++ b/src/pfsys/mod.rs @@ -46,6 +46,9 @@ use thiserror::Error as thisError; #[cfg(all(feature = "ezkl", not(target_arch = "wasm32")))] use tosubcommand::ToFlags; +#[cfg(feature = "python-bindings")] +use pyo3::types::PyDictMethods; + use halo2curves::bn256::{Bn256, Fr, G1Affine}; fn serde_format_from_str(s: &str) -> halo2_proofs::SerdeFormat { @@ -116,9 +119,8 @@ impl ToPyObject for ProofType { #[cfg(feature = "python-bindings")] /// Obtains StrategyType from PyObject (Required for StrategyType to be compatible with Python) impl<'source> pyo3::FromPyObject<'source> for ProofType { - fn extract(ob: &'source pyo3::PyAny) -> pyo3::PyResult { - let trystr = ::try_from(ob)?; - let strval = trystr.to_string(); + fn extract_bound(ob: &pyo3::Bound<'source, pyo3::PyAny>) -> pyo3::PyResult { + let strval = String::extract_bound(ob)?; match strval.to_lowercase().as_str() { "single" => Ok(ProofType::Single), "for-aggr" => Ok(ProofType::ForAggr), @@ -174,9 +176,8 @@ impl pyo3::IntoPy for StrategyType { #[cfg(feature = "python-bindings")] /// Obtains StrategyType from PyObject (Required for StrategyType to be compatible with Python) impl<'source> pyo3::FromPyObject<'source> for StrategyType { - fn extract(ob: &'source pyo3::PyAny) -> pyo3::PyResult { - let trystr = ::try_from(ob)?; - let strval = trystr.to_string(); + fn extract_bound(ob: &pyo3::Bound<'source, pyo3::PyAny>) -> pyo3::PyResult { + let strval = String::extract_bound(ob)?; match strval.to_lowercase().as_str() { "single" => Ok(StrategyType::Single), "accum" => Ok(StrategyType::Accum), @@ -235,7 +236,7 @@ impl ToPyObject for TranscriptType { #[cfg(feature = "python-bindings")] /// -pub fn g1affine_to_pydict(g1affine_dict: &PyDict, g1affine: &G1Affine) { +pub fn g1affine_to_pydict(g1affine_dict: &pyo3::Bound<'_, PyDict>, g1affine: &G1Affine) { let g1affine_x = field_to_string(&g1affine.x); let g1affine_y = field_to_string(&g1affine.y); g1affine_dict.set_item("x", g1affine_x).unwrap(); @@ -246,7 +247,7 @@ pub fn g1affine_to_pydict(g1affine_dict: &PyDict, g1affine: &G1Affine) { use halo2curves::bn256::G1; #[cfg(feature = "python-bindings")] /// -pub fn g1_to_pydict(g1_dict: &PyDict, g1: &G1) { +pub fn g1_to_pydict(g1_dict: &pyo3::Bound<'_, PyDict>, g1: &G1) { let g1_x = field_to_string(&g1.x); let g1_y = field_to_string(&g1.y); let g1_z = field_to_string(&g1.z); @@ -337,7 +338,7 @@ where dict.set_item("instances", field_elems).unwrap(); let hex_proof = hex::encode(&self.proof); dict.set_item("proof", format!("0x{}", hex_proof)).unwrap(); - dict.set_item("transcript_type", self.transcript_type) + dict.set_item("transcript_type", self.transcript_type.to_object(py)) .unwrap(); dict.to_object(py) } diff --git a/tests/py_integration_tests.rs b/tests/py_integration_tests.rs index 6a0bba604..abb6c9129 100644 --- a/tests/py_integration_tests.rs +++ b/tests/py_integration_tests.rs @@ -189,6 +189,17 @@ mod py_tests { anvil_child.kill().unwrap(); } }); + + #[test] + fn felt_conversion_test_notebook() { + crate::py_tests::init_binary(); + let test_dir: TempDir = TempDir::new("felt_conversion_test").unwrap(); + let path = test_dir.path().to_str().unwrap(); + crate::py_tests::mv_test_(path, "felt_conversion_test.ipynb"); + run_notebook(path, "felt_conversion_test.ipynb"); + test_dir.close().unwrap(); + } + #[test] fn voice_notebook_() { crate::py_tests::init_binary(); From f5b8ae321302819c0c821907ccea5b4a99d12ff5 Mon Sep 17 00:00:00 2001 From: Jseam Date: Fri, 6 Dec 2024 02:46:40 +0700 Subject: [PATCH 2/2] fix: revert pypi to 1.11.0 (#880) --- .github/workflows/pypi-gpu.yml | 4 ++-- .github/workflows/pypi.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pypi-gpu.yml b/.github/workflows/pypi-gpu.yml index f2af962a2..7730faf5e 100644 --- a/.github/workflows/pypi-gpu.yml +++ b/.github/workflows/pypi-gpu.yml @@ -98,14 +98,14 @@ jobs: # publishes to PyPI - name: Publish package distributions to PyPI continue-on-error: true - uses: pypa/gh-action-pypi-publish@release/v1 + uses: pypa/gh-action-pypi-publish@release/v1.11.0 with: packages-dir: ./ # publishes to TestPyPI - name: Publish package distribution to TestPyPI continue-on-error: true - uses: pypa/gh-action-pypi-publish@release/v1 + uses: pypa/gh-action-pypi-publish@release/v1.11.0 with: repository-url: https://test.pypi.org/legacy/ packages-dir: ./ diff --git a/.github/workflows/pypi.yml b/.github/workflows/pypi.yml index 465ef82d3..06d7d2c17 100644 --- a/.github/workflows/pypi.yml +++ b/.github/workflows/pypi.yml @@ -348,14 +348,14 @@ jobs: # publishes to PyPI - name: Publish package distributions to PyPI continue-on-error: true - uses: pypa/gh-action-pypi-publish@release/v1 + uses: pypa/gh-action-pypi-publish@release/v1.11.0 with: packages-dir: ./ # publishes to TestPyPI - name: Publish package distribution to TestPyPI continue-on-error: true - uses: pypa/gh-action-pypi-publish@release/v1 + uses: pypa/gh-action-pypi-publish@release/v1.11.0 with: repository-url: https://test.pypi.org/legacy/ packages-dir: ./