Compare commits

..

21 Commits

Author SHA1 Message Date
dante
e4b6cf445c Update integration_tests.rs 2025-07-23 15:07:29 -04:00
dante
3c7c1fd204 Update rust.yml 2025-07-23 14:23:25 -04:00
dante
94e8664f2e Update rust.yml 2025-07-23 12:35:49 -04:00
dante
960bcb1a56 downgrade by a day 2025-07-23 12:19:36 -04:00
dante
054aaf4938 Update python.rs 2025-07-23 10:34:53 -04:00
dante
cfeb3143db Update integration_tests.rs 2025-07-23 10:30:58 -04:00
dante
5c2f8079b0 update deprecated maturin 2025-07-23 10:26:50 -04:00
dante
24160d887e Update rust.yml 2025-07-22 19:12:28 -04:00
dante
ef7441f3cf bump toolchain 2025-07-22 18:56:21 -04:00
dante
b94f1a03fc bump toolchain 2025-07-22 18:31:06 -04:00
dante
c5dd3e7e7f Update rust.yml 2025-07-22 18:22:55 -04:00
dante
ab56aabf2e Update rust.yml 2025-07-22 18:21:05 -04:00
dante
7f54650647 Update rust.yml 2025-07-22 18:17:25 -04:00
dante
8a7b06ee2f Update integration_tests.rs 2025-07-22 18:15:50 -04:00
dante
92ef831185 Update integration_tests.rs 2025-07-22 18:03:02 -04:00
dante
f64ccf7512 Update layouts.rs 2025-07-22 17:56:36 -04:00
dante
c703b9ad82 Update rust.yml 2025-07-22 17:50:33 -04:00
dante
87327cab96 patch python 2025-07-22 17:41:16 -04:00
dante
6e168f4bc4 Update input.rs 2025-07-22 15:58:07 -04:00
dante
d3495b2f69 refactor: backwards compatible 2025-07-22 15:43:29 -04:00
dante
398bcb5928 fix: allow insecure for new runner 2025-07-22 14:52:48 -04:00
18 changed files with 828 additions and 215 deletions

View File

@@ -29,7 +29,7 @@ jobs:
persist-credentials: false
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
with:
toolchain: nightly-2025-02-17
toolchain: nightly-2025-06-16
override: true
components: rustfmt, clippy
- uses: jetli/wasm-pack-action@0d096b08b4e5a7de8c28de67e11e945404e9eefa #v0.4.0
@@ -40,7 +40,7 @@ jobs:
run: rustup target add wasm32-unknown-unknown
- name: Add rust-src
run: rustup component add rust-src --toolchain nightly-2025-02-17-x86_64-unknown-linux-gnu
run: rustup component add rust-src --toolchain nightly-2025-06-16-x86_64-unknown-linux-gnu
- name: Install binaryen
run: |
set -e

View File

@@ -15,7 +15,7 @@ jobs:
persist-credentials: false
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
with:
toolchain: nightly-2025-02-17
toolchain: nightly-2025-06-16
override: true
components: rustfmt, clippy
- name: nanoGPT Mock

View File

@@ -50,7 +50,7 @@ jobs:
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
with:
toolchain: nightly-2025-02-17
toolchain: nightly-2025-06-16
override: true
components: rustfmt, clippy
@@ -115,7 +115,7 @@ jobs:
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
with:
toolchain: nightly-2025-02-17
toolchain: nightly-2025-06-16
override: true
components: rustfmt, clippy

View File

@@ -50,7 +50,7 @@ jobs:
steps:
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
with:
toolchain: nightly-2025-02-17
toolchain: nightly-2025-06-16
override: true
components: rustfmt, clippy
- name: Checkout repo
@@ -117,27 +117,27 @@ jobs:
include:
- build: windows-msvc
os: windows-latest
rust: nightly-2025-02-17
rust: nightly-2025-06-16
target: x86_64-pc-windows-msvc
- build: macos
os: macos-13
rust: nightly-2025-02-17
rust: nightly-2025-06-16
target: x86_64-apple-darwin
- build: macos-aarch64
os: macos-13
rust: nightly-2025-02-17
rust: nightly-2025-06-16
target: aarch64-apple-darwin
- build: linux-musl
os: ubuntu-22.04
rust: nightly-2025-02-17
rust: nightly-2025-06-16
target: x86_64-unknown-linux-musl
- build: linux-gnu
os: ubuntu-22.04
rust: nightly-2025-02-17
rust: nightly-2025-06-16
target: x86_64-unknown-linux-gnu
- build: linux-aarch64
os: ubuntu-22.04
rust: nightly-2025-02-17
rust: nightly-2025-06-16
target: aarch64-unknown-linux-gnu
steps:

View File

@@ -31,9 +31,9 @@ jobs:
with:
persist-credentials: false
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
with:
toolchain: nightly-2025-02-17
toolchain: nightly-2025-06-16
override: true
components: rustfmt, clippy
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3
@@ -55,9 +55,9 @@ jobs:
persist-credentials: false
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
with:
toolchain: nightly-2025-02-17
toolchain: nightly-2025-06-16
override: true
components: rustfmt, clippy
- name: Build
@@ -73,9 +73,9 @@ jobs:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
with:
toolchain: nightly-2025-02-17
toolchain: nightly-2025-06-16
override: true
components: rustfmt, clippy
- name: Docs
@@ -91,9 +91,9 @@ jobs:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
with:
toolchain: nightly-2025-02-17
toolchain: nightly-2025-06-16
override: true
components: rustfmt, clippy
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
@@ -116,9 +116,9 @@ jobs:
# - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
# with:
# persist-credentials: false
# - uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
# - uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
# with:
# toolchain: nightly-2025-02-17
# toolchain: nightly-2025-06-16
# override: true
# components: rustfmt, clippy
# - uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
@@ -144,7 +144,7 @@ jobs:
ultra-overflow-tests_og-lookup:
permissions:
contents: read
runs-on: non-gpu
runs-on: non-gpu,non-sgx
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
steps:
@@ -152,9 +152,9 @@ jobs:
with:
persist-credentials: false
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
with:
toolchain: nightly-2025-02-17
toolchain: nightly-2025-06-16
override: true
components: rustfmt, clippy
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
@@ -180,20 +180,22 @@ jobs:
ultra-overflow-tests:
permissions:
contents: read
runs-on: non-gpu
runs-on: non-gpu,non-sgx
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
with:
toolchain: nightly-2025-02-17
toolchain: nightly-2025-06-16
override: true
components: rustfmt, clippy
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
with:
crate: cargo-nextest
@@ -220,15 +222,16 @@ jobs:
runs-on: ubuntu-latest-16-cores
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
with:
toolchain: nightly-2025-02-17
toolchain: nightly-2025-06-16
override: true
components: rustfmt, clippy
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
@@ -244,15 +247,18 @@ jobs:
runs-on: ubuntu-latest-64-cores
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
# add `atomics` and `bulk-memory` to RUSTFLAGS to enable wasm-bindgen tests
RUSTFLAGS: "-C target-feature=+atomics,+bulk-memory"
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
with:
toolchain: nightly-2025-02-17
toolchain: nightly-2025-06-16
override: true
components: rustfmt, clippy
- uses: jetli/wasm-pack-action@0d096b08b4e5a7de8c28de67e11e945404e9eefa #v0.4.0
@@ -265,7 +271,7 @@ jobs:
- name: Install wasm32-unknown-unknown
run: rustup target add wasm32-unknown-unknown
- name: Add rust-src
run: rustup component add rust-src --toolchain nightly-2025-02-17-x86_64-unknown-linux-gnu
run: rustup component add rust-src --toolchain nightly-2025-06-16-x86_64-unknown-linux-gnu
- name: Create webdriver.json to disable timeouts
run: |
echo '{"args": ["--headless", "--disable-gpu", "--disable-dev-shm-usage", "--no-sandbox"]}' > webdriver.json
@@ -280,7 +286,7 @@ jobs:
mock-proving-tests:
permissions:
contents: read
runs-on: non-gpu
runs-on: non-gpu,non-sgx
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
@@ -288,10 +294,10 @@ jobs:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
with:
toolchain: nightly-2025-02-17
toolchain: nightly-2025-06-16
override: true
components: rustfmt, clippy
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
@@ -350,21 +356,27 @@ jobs:
prove-and-verify-evm-tests:
permissions:
contents: read
runs-on: non-gpu
runs-on: non-gpu,non-sgx
# needs: [build, library-tests, docs, python-tests, python-integration-tests]
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
RUSTFLAGS: "-C target-feature=+atomics,+bulk-memory"
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
with:
toolchain: nightly-2025-02-17
toolchain: nightly-2025-06-16
override: true
components: rustfmt, clippy
- uses: jetli/wasm-pack-action@0d096b08b4e5a7de8c28de67e11e945404e9eefa #v0.4.0
with:
# Pin to version 0.12.1
version: "v0.12.1"
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
with:
crate: cargo-nextest
@@ -382,14 +394,14 @@ jobs:
node-version: "18.12.1"
cache: "pnpm"
- name: "Add rust-src"
run: rustup component add rust-src --toolchain nightly-2025-02-17-x86_64-unknown-linux-gnu
run: rustup component add rust-src --toolchain nightly-2025-06-16-x86_64-unknown-linux-gnu
- name: Install dependencies for js tests and package
run: |
pnpm install --frozen-lockfile
# - name: Install solc
# run: (hash svm 2>/dev/null || cargo install svm-rs) && svm install 0.8.20 && solc --version
- name: Install Anvil
run: cargo install --git https://github.com/foundry-rs/foundry --rev 62cdea8ff9e6efef011f77e295823b5f2dbeb3a1 --locked anvil --force
run: cargo install --git https://github.com/foundry-rs/foundry --rev 56b806a3ba7866a3b061093bebd0fa2ace97f1fc --locked anvil --force
- name: Build wasm package for nodejs target.
run: |
wasm-pack build --target nodejs --out-dir ./tests/wasm/nodejs . -- -Z build-std="panic_abort,std"
@@ -419,9 +431,9 @@ jobs:
# - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
# with:
# persist-credentials: false
# - uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
# - uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
# with:
# toolchain: nightly-2025-02-17
# toolchain: nightly-2025-06-16
# override: true
# components: rustfmt, clippy
# - uses: jetli/wasm-pack-action@0d096b08b4e5a7de8c28de67e11e945404e9eefa #v0.4.0
@@ -429,7 +441,7 @@ jobs:
# # Pin to version 0.12.1
# version: 'v0.12.1'
# - name: Add rust-src
# run: rustup component add rust-src --toolchain nightly-2025-02-17
# run: rustup component add rust-src --toolchain nightly-2025-06-16
# - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
# with:
# persist-credentials: false
@@ -447,19 +459,21 @@ jobs:
prove-and-verify-tests:
permissions:
contents: read
runs-on: non-gpu
runs-on: non-gpu,non-sgx
needs: [build, library-tests, docs]
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
RUSTFLAGS: "-C target-feature=+atomics,+bulk-memory"
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
with:
toolchain: nightly-2025-02-17
toolchain: nightly-2025-06-16
override: true
components: rustfmt, clippy
- uses: jetli/wasm-pack-action@0d096b08b4e5a7de8c28de67e11e945404e9eefa #v0.4.0
@@ -470,7 +484,7 @@ jobs:
run: rustup target add wasm32-unknown-unknown
- name: Add rust-src
run: rustup component add rust-src --toolchain nightly-2025-02-17-x86_64-unknown-linux-gnu
run: rustup component add rust-src --toolchain nightly-2025-06-16-x86_64-unknown-linux-gnu
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
@@ -535,13 +549,13 @@ jobs:
# - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
# with:
# persist-credentials: false
# - uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
# - uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
# with:
# toolchain: nightly-2025-02-17
# toolchain: nightly-2025-06-16
# override: true
# components: rustfmt, clippy
# - name: Add rust-src
# run: rustup component add rust-src --toolchain nightly-2025-02-17-x86_64-unknown-linux-gnu
# run: rustup component add rust-src --toolchain nightly-2025-06-16-x86_64-unknown-linux-gnu
# - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
# - uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
# with:
@@ -571,15 +585,16 @@ jobs:
needs: [build, library-tests, docs, python-tests, python-integration-tests]
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- uses: dtolnay/rust-toolchain@4f94fbe7e03939b0e674bcc9ca609a16088f63ff #nightly branch, TODO: update when required
with:
toolchain: nightly-2025-02-17
toolchain: nightly-2025-06-16
override: true
components: rustfmt, clippy
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
@@ -597,9 +612,9 @@ jobs:
# - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
# with:
# persist-credentials: false
# - uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
# - uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
# with:
# toolchain: nightly-2025-02-17
# toolchain: nightly-2025-06-16
# override: true
# components: rustfmt, clippy
# - uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
@@ -616,15 +631,16 @@ jobs:
needs: [build, library-tests, docs, python-tests, python-integration-tests]
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
with:
toolchain: nightly-2025-02-17
toolchain: nightly-2025-06-16
override: true
components: rustfmt, clippy
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
@@ -641,15 +657,16 @@ jobs:
needs: [build, library-tests, docs, python-tests, python-integration-tests]
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
with:
toolchain: nightly-2025-02-17
toolchain: nightly-2025-06-16
override: true
components: rustfmt, clippy
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
@@ -659,7 +676,7 @@ jobs:
# - name: Install solc
# run: (hash svm 2>/dev/null || cargo install svm-rs) && svm install 0.8.20 && solc --version
- name: Install Anvil
run: cargo install --git https://github.com/foundry-rs/foundry --rev 62cdea8ff9e6efef011f77e295823b5f2dbeb3a1 --locked anvil --force
run: cargo install --git https://github.com/foundry-rs/foundry --rev 56b806a3ba7866a3b061093bebd0fa2ace97f1fc --locked anvil --force
- name: KZG prove and verify aggr tests
run: cargo nextest run --verbose tests_evm::kzg_evm_aggr_prove_and_verify_::t --test-threads 4 -- --include-ignored
@@ -670,15 +687,16 @@ jobs:
needs: [build, library-tests, docs]
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
with:
toolchain: nightly-2025-02-17
toolchain: nightly-2025-06-16
override: true
components: rustfmt, clippy
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
@@ -691,22 +709,23 @@ jobs:
python-tests:
permissions:
contents: read
runs-on: non-gpu
runs-on: non-gpu,non-sgx
needs: [build, library-tests, docs]
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- uses: actions/setup-python@b64ffcaf5b410884ad320a9cfac8866006a109aa #v4.8.0
with:
python-version: "3.12"
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
with:
toolchain: nightly-2025-02-17
toolchain: nightly-2025-06-16
override: true
components: rustfmt, clippy
- name: Install cmake
@@ -716,7 +735,7 @@ jobs:
- name: Setup Virtual Env and Install python dependencies
run: python -m venv .env --clear; source .env/bin/activate; pip install -r requirements.txt;
- name: Install Anvil
run: cargo install --git https://github.com/foundry-rs/foundry --rev 62cdea8ff9e6efef011f77e295823b5f2dbeb3a1 --locked anvil --force
run: cargo install --git https://github.com/foundry-rs/foundry --rev 56b806a3ba7866a3b061093bebd0fa2ace97f1fc --locked anvil --force
- name: Build python ezkl
run: source .env/bin/activate; unset CONDA_PREFIX; maturin develop --features python-bindings,reusable-verifier --profile=test-runs
- name: Run pytest
@@ -725,22 +744,23 @@ jobs:
accuracy-measurement-tests:
permissions:
contents: read
runs-on: non-gpu
runs-on: non-gpu,non-sgx
needs: [build, library-tests, docs, python-tests, python-integration-tests]
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- uses: actions/setup-python@b64ffcaf5b410884ad320a9cfac8866006a109aa #v4.8.0
with:
python-version: "3.12"
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
with:
toolchain: nightly-2025-02-17
toolchain: nightly-2025-06-16
override: true
components: rustfmt, clippy
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
@@ -766,18 +786,19 @@ jobs:
runs-on: large-self-hosted
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- uses: actions/setup-python@b64ffcaf5b410884ad320a9cfac8866006a109aa #v4.8.0
with:
python-version: "3.11"
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
with:
toolchain: nightly-2025-02-17
toolchain: nightly-2025-06-16
override: true
components: rustfmt, clippy
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
@@ -787,7 +808,7 @@ jobs:
# - name: Install solc
# run: (hash svm 2>/dev/null || cargo install svm-rs) && svm install 0.8.20 && solc --version
- name: Install Anvil
run: cargo install --git https://github.com/foundry-rs/foundry --rev 62cdea8ff9e6efef011f77e295823b5f2dbeb3a1 --locked anvil --force
run: cargo install --git https://github.com/foundry-rs/foundry --rev 56b806a3ba7866a3b061093bebd0fa2ace97f1fc --locked anvil --force
- name: Install pip
run: python -m ensurepip --upgrade
- name: Setup Virtual Env and Install python dependencies
@@ -828,15 +849,16 @@ jobs:
runs-on: macos-latest
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
with:
toolchain: nightly-2025-02-17
toolchain: nightly-2025-06-16
override: true
components: rustfmt, clippy
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
@@ -844,7 +866,7 @@ jobs:
crate: cargo-nextest
locked: true
- name: Run ios tests
run: CARGO_BUILD_TARGET=aarch64-apple-darwin RUSTUP_TOOLCHAIN=nightly-2025-02-17-aarch64-apple-darwin cargo test --test ios_integration_tests --features ios-bindings-test --no-default-features
run: CARGO_BUILD_TARGET=aarch64-apple-darwin RUSTUP_TOOLCHAIN=nightly-2025-06-16-aarch64-apple-darwin cargo test --test ios_integration_tests --features ios-bindings-test --no-default-features
swift-package-tests:
permissions:
@@ -854,14 +876,15 @@ jobs:
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
with:
toolchain: nightly-2025-02-17
toolchain: nightly-2025-06-16
override: true
components: rustfmt, clippy
- name: Build EzklCoreBindings

View File

@@ -17,7 +17,7 @@ jobs:
persist-credentials: false
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
with:
toolchain: nightly-2025-02-17
toolchain: nightly-2025-06-16
override: true
components: rustfmt, clippy

View File

@@ -1,7 +1,7 @@
import ezkl
project = 'ezkl'
release = '22.1.4'
release = '0.0.0'
version = release

View File

@@ -1,3 +1,3 @@
[toolchain]
channel = "nightly-2025-02-17"
channel = "nightly-2025-06-16"
components = ["rustfmt", "clippy"]

View File

@@ -93,16 +93,6 @@ impl From<PyG1> for G1 {
}
}
impl pyo3::ToPyObject for PyG1 {
fn to_object(&self, py: pyo3::Python) -> pyo3::PyObject {
let g1_dict = pyo3::types::PyDict::new(py);
g1_dict.set_item("x", self.x.to_object(py)).unwrap();
g1_dict.set_item("y", self.y.to_object(py)).unwrap();
g1_dict.set_item("z", self.z.to_object(py)).unwrap();
g1_dict.into()
}
}
/// pyclass containing the struct used for G1
#[pyclass]
@@ -135,15 +125,6 @@ impl From<PyG1Affine> for G1Affine {
}
}
impl pyo3::ToPyObject for PyG1Affine {
fn to_object(&self, py: pyo3::Python) -> pyo3::PyObject {
let g1_dict = pyo3::types::PyDict::new(py);
g1_dict.set_item("x", self.x.to_object(py)).unwrap();
g1_dict.set_item("y", self.y.to_object(py)).unwrap();
g1_dict.into()
}
}
/// Python class containing the struct used for run_args
///
@@ -884,7 +865,7 @@ fn gen_srs(srs_path: PathBuf, logrows: usize) -> PyResult<()> {
))]
#[gen_stub_pyfunction]
fn get_srs(
py: Python,
py: Python<'_>,
settings_path: Option<PathBuf>,
logrows: Option<u32>,
srs_path: Option<PathBuf>,
@@ -1101,7 +1082,7 @@ fn gen_witness(
let err_str = format!("Failed to generate witness: {}", e);
PyRuntimeError::new_err(err_str)
})?;
Python::with_gil(|py| Ok(output.to_object(py)))
Python::with_gil(|py| Ok(output.into_pyobject(py).unwrap().into()))
}
/// Mocks the prover
@@ -1283,7 +1264,7 @@ fn prove(
PyRuntimeError::new_err(err_str)
})?;
Python::with_gil(|py| Ok(snark.to_object(py)))
Python::with_gil(|py| Ok(snark.into_pyobject(py).unwrap().into()))
}
/// Verifies a given proof
@@ -1649,7 +1630,7 @@ fn encode_evm_calldata<'a>(
))]
#[gen_stub_pyfunction]
fn create_evm_verifier(
py: Python,
py: Python<'_>,
vk_path: PathBuf,
settings_path: PathBuf,
sol_code_path: PathBuf,
@@ -1710,7 +1691,7 @@ fn create_evm_verifier(
))]
#[gen_stub_pyfunction]
fn create_evm_vka(
py: Python,
py: Python<'_>,
vk_path: PathBuf,
settings_path: PathBuf,
vka_path: PathBuf,
@@ -1740,7 +1721,7 @@ fn create_evm_vka(
))]
#[gen_stub_pyfunction]
fn deploy_evm(
py: Python,
py: Python<'_>,
addr_path: PathBuf,
rpc_url: String,
sol_code_path: PathBuf,
@@ -1924,7 +1905,7 @@ fn verify_evm<'a>(
))]
#[gen_stub_pyfunction]
fn create_evm_verifier_aggr(
py: Python,
py: Python<'_>,
aggregation_settings: Vec<PathBuf>,
vk_path: PathBuf,
sol_code_path: PathBuf,

View File

@@ -8,8 +8,9 @@ use halo2_proofs::{
use log::debug;
#[cfg(feature = "python-bindings")]
use pyo3::{
conversion::{FromPyObject, IntoPy},
conversion::FromPyObject,
exceptions::PyValueError,
IntoPyObject,
prelude::*,
};
use serde::{Deserialize, Serialize};
@@ -86,12 +87,17 @@ impl CheckMode {
#[cfg(feature = "python-bindings")]
/// Converts CheckMode into a PyObject (Required for CheckMode to be compatible with Python)
impl IntoPy<PyObject> for CheckMode {
fn into_py(self, py: Python) -> PyObject {
match self {
CheckMode::SAFE => "safe".to_object(py),
CheckMode::UNSAFE => "unsafe".to_object(py),
}
impl<'py> IntoPyObject<'py> for CheckMode {
type Target = pyo3::PyAny;
type Output = pyo3::Bound<'py, Self::Target>;
type Error = pyo3::PyErr;
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
let result = match self {
CheckMode::SAFE => "safe",
CheckMode::UNSAFE => "unsafe",
};
Ok(result.into_pyobject(py)?.into_any())
}
}

View File

@@ -4626,7 +4626,7 @@ pub(crate) fn rescale<F: PrimeField + TensorType + PartialOrd + std::hash::Hash>
let mut rescaled_inputs = vec![];
for (i, ri) in values.iter().enumerate() {
if scales[i].1 == 1 {
rescaled_inputs.push(ri.clone().clone());
rescaled_inputs.push((*ri).clone());
continue;
}

View File

@@ -93,12 +93,17 @@ pub const DEFAULT_VKA_DIGEST: &str = "vka.digest";
#[cfg(feature = "python-bindings")]
/// Converts TranscriptType into a PyObject (Required for TranscriptType to be compatible with Python)
impl IntoPy<PyObject> for TranscriptType {
fn into_py(self, py: Python) -> PyObject {
match self {
TranscriptType::Poseidon => "poseidon".to_object(py),
TranscriptType::EVM => "evm".to_object(py),
}
impl<'py> IntoPyObject<'py> for TranscriptType {
type Target = pyo3::PyAny;
type Output = pyo3::Bound<'py, Self::Target>;
type Error = pyo3::PyErr;
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
let result = match self {
TranscriptType::Poseidon => "poseidon",
TranscriptType::EVM => "evm",
};
Ok(result.into_pyobject(py)?.into_any())
}
}
#[cfg(feature = "python-bindings")]
@@ -257,17 +262,22 @@ impl From<&str> for H160Flag {
#[cfg(feature = "python-bindings")]
/// Converts CalibrationTarget into a PyObject (Required for CalibrationTarget to be compatible with Python)
impl IntoPy<PyObject> for CalibrationTarget {
fn into_py(self, py: Python) -> PyObject {
match self {
impl<'py> IntoPyObject<'py> for CalibrationTarget {
type Target = pyo3::PyAny;
type Output = pyo3::Bound<'py, Self::Target>;
type Error = pyo3::PyErr;
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
let result = match self {
CalibrationTarget::Resources { col_overflow: true } => {
"resources/col-overflow".to_object(py)
"resources/col-overflow"
}
CalibrationTarget::Resources {
col_overflow: false,
} => "resources".to_object(py),
CalibrationTarget::Accuracy => "accuracy".to_object(py),
}
} => "resources",
CalibrationTarget::Accuracy => "accuracy",
};
Ok(result.into_pyobject(py)?.into_any())
}
}
@@ -289,12 +299,17 @@ impl<'source> FromPyObject<'source> for CalibrationTarget {
#[cfg(feature = "python-bindings")]
/// Converts ContractType into a PyObject (Required for ContractType to be compatible with Python)
impl IntoPy<PyObject> 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),
}
impl<'py> IntoPyObject<'py> for ContractType {
type Target = pyo3::PyAny;
type Output = pyo3::Bound<'py, Self::Target>;
type Error = pyo3::PyErr;
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
let result = match self {
ContractType::Verifier { reusable: true } => "verifier/reusable",
ContractType::Verifier { reusable: false } => "verifier",
};
Ok(result.into_pyobject(py)?.into_any())
}
}

View File

@@ -7,9 +7,7 @@ use halo2curves::bn256::Fr as Fp;
#[cfg(feature = "python-bindings")]
use pyo3::prelude::*;
#[cfg(feature = "python-bindings")]
use pyo3::types::PyDict;
#[cfg(feature = "python-bindings")]
use pyo3::ToPyObject;
use pyo3::IntoPyObject;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::io::BufReader;
use std::io::BufWriter;
@@ -429,34 +427,29 @@ mod tests {
}
}
#[cfg(feature = "python-bindings")]
impl ToPyObject for CallToAccount {
fn to_object(&self, py: Python) -> PyObject {
let dict = PyDict::new(py);
dict.set_item("account", &self.address).unwrap();
dict.set_item("call_data", &self.call_data).unwrap();
dict.set_item("decimals", &self.decimals).unwrap();
dict.to_object(py)
}
}
#[cfg(feature = "python-bindings")]
impl ToPyObject for DataSource {
fn to_object(&self, py: Python) -> PyObject {
self.0.to_object(py)
}
}
#[cfg(feature = "python-bindings")]
use crate::pfsys::field_to_string;
#[cfg(feature = "python-bindings")]
impl ToPyObject for FileSourceInner {
fn to_object(&self, py: Python) -> PyObject {
impl<'py> IntoPyObject<'py> for FileSourceInner {
type Target = pyo3::PyAny;
type Output = pyo3::Bound<'py, Self::Target>;
type Error = pyo3::PyErr;
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
match self {
FileSourceInner::Field(data) => field_to_string(data).to_object(py),
FileSourceInner::Bool(data) => data.to_object(py),
FileSourceInner::Float(data) => data.to_object(py),
FileSourceInner::Field(data) => {
let s = field_to_string(&data);
Ok(pyo3::types::PyString::new(py, &s).into_any())
},
FileSourceInner::Bool(data) => {
Ok(pyo3::types::PyBool::new(py, data).as_any().clone())
},
FileSourceInner::Float(data) => {
Ok(pyo3::types::PyFloat::new(py, data).into_any())
},
}
}
}

View File

@@ -61,7 +61,7 @@ use pyo3::types::PyDict;
#[cfg(feature = "python-bindings")]
use pyo3::types::PyDictMethods;
#[cfg(feature = "python-bindings")]
use pyo3::ToPyObject;
use pyo3::IntoPyObject;
use serde::{Deserialize, Serialize};
use std::ops::Deref;
@@ -319,8 +319,12 @@ impl GraphWitness {
}
#[cfg(feature = "python-bindings")]
impl ToPyObject for GraphWitness {
fn to_object(&self, py: Python) -> PyObject {
impl<'py> IntoPyObject<'py> for GraphWitness {
type Target = pyo3::PyAny;
type Output = pyo3::Bound<'py, Self::Target>;
type Error = pyo3::PyErr;
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
// Create a Python dictionary
let dict = PyDict::new(py);
let dict_inputs = PyDict::new(py);
@@ -383,7 +387,7 @@ impl ToPyObject for GraphWitness {
dict.set_item("processed_outputs", dict_outputs).unwrap();
}
dict.to_object(py)
Ok(dict.into_any())
}
}
@@ -435,7 +439,7 @@ pub struct ShuffleParams {
}
/// model parameters
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)]
#[derive(Clone, Debug, Default, PartialEq)]
pub struct GraphSettings {
/// run args
pub run_args: RunArgs,
@@ -445,11 +449,9 @@ pub struct GraphSettings {
pub total_assignments: usize,
/// total const size
pub total_const_size: usize,
/// dynamic lookup parameters, flattened for backwards compatibility
#[serde(flatten)]
/// dynamic lookup parameters, flattened for backwards compatibility, serialize and deserialize flattened for backwards compatibility
pub dynamic_lookup_params: DynamicLookupParams,
/// shuffle parameters, flattened for backwards compatibility
#[serde(flatten)]
pub shuffle_params: ShuffleParams,
/// the shape of public inputs to the model (in order of appearance)
pub model_instance_shapes: Vec<Vec<usize>>,
@@ -477,6 +479,434 @@ pub struct GraphSettings {
pub output_types: Option<Vec<InputType>>,
}
impl Serialize for GraphSettings {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
if serializer.is_human_readable() {
// JSON format - use flattened fields for backwards compatibility
use serde::ser::SerializeStruct;
let mut state = serializer.serialize_struct("GraphSettings", 21)?;
state.serialize_field("run_args", &self.run_args)?;
state.serialize_field("num_rows", &self.num_rows)?;
state.serialize_field("total_assignments", &self.total_assignments)?;
state.serialize_field("total_const_size", &self.total_const_size)?;
// Flatten DynamicLookupParams fields
state.serialize_field(
"total_dynamic_col_size",
&self.dynamic_lookup_params.total_dynamic_col_size,
)?;
state.serialize_field(
"max_dynamic_input_len",
&self.dynamic_lookup_params.max_dynamic_input_len,
)?;
state.serialize_field(
"num_dynamic_lookups",
&self.dynamic_lookup_params.num_dynamic_lookups,
)?;
// Flatten ShuffleParams fields
state.serialize_field("num_shuffles", &self.shuffle_params.num_shuffles)?;
state.serialize_field(
"total_shuffle_col_size",
&self.shuffle_params.total_shuffle_col_size,
)?;
state.serialize_field("model_instance_shapes", &self.model_instance_shapes)?;
state.serialize_field("model_output_scales", &self.model_output_scales)?;
state.serialize_field("model_input_scales", &self.model_input_scales)?;
state.serialize_field("module_sizes", &self.module_sizes)?;
state.serialize_field("required_lookups", &self.required_lookups)?;
state.serialize_field("required_range_checks", &self.required_range_checks)?;
state.serialize_field("check_mode", &self.check_mode)?;
state.serialize_field("version", &self.version)?;
state.serialize_field("num_blinding_factors", &self.num_blinding_factors)?;
state.serialize_field("timestamp", &self.timestamp)?;
state.serialize_field("input_types", &self.input_types)?;
state.serialize_field("output_types", &self.output_types)?;
state.end()
} else {
// Binary format (bincode) - use nested struct format
use serde::ser::SerializeTuple;
let mut state = serializer.serialize_tuple(18)?;
state.serialize_element(&self.run_args)?;
state.serialize_element(&self.num_rows)?;
state.serialize_element(&self.total_assignments)?;
state.serialize_element(&self.total_const_size)?;
state.serialize_element(&self.dynamic_lookup_params)?;
state.serialize_element(&self.shuffle_params)?;
state.serialize_element(&self.model_instance_shapes)?;
state.serialize_element(&self.model_output_scales)?;
state.serialize_element(&self.model_input_scales)?;
state.serialize_element(&self.module_sizes)?;
state.serialize_element(&self.required_lookups)?;
state.serialize_element(&self.required_range_checks)?;
state.serialize_element(&self.check_mode)?;
state.serialize_element(&self.version)?;
state.serialize_element(&self.num_blinding_factors)?;
state.serialize_element(&self.timestamp)?;
state.serialize_element(&self.input_types)?;
state.serialize_element(&self.output_types)?;
state.end()
}
}
}
impl<'de> Deserialize<'de> for GraphSettings {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
use serde::de::{self, MapAccess, Visitor};
use std::fmt;
#[derive(Deserialize)]
#[serde(field_identifier, rename_all = "snake_case")]
enum Field {
RunArgs,
NumRows,
TotalAssignments,
TotalConstSize,
// Flattened DynamicLookupParams fields
TotalDynamicColSize,
MaxDynamicInputLen,
NumDynamicLookups,
// Flattened ShuffleParams fields
NumShuffles,
TotalShuffleColSize,
ModelInstanceShapes,
ModelOutputScales,
ModelInputScales,
ModuleSizes,
RequiredLookups,
RequiredRangeChecks,
CheckMode,
Version,
NumBlindingFactors,
Timestamp,
InputTypes,
OutputTypes,
// Legacy nested struct fields for backwards compatibility
DynamicLookupParams,
ShuffleParams,
}
struct GraphSettingsVisitor;
impl<'de> Visitor<'de> for GraphSettingsVisitor {
type Value = GraphSettings;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("struct GraphSettings")
}
fn visit_map<V>(self, mut map: V) -> Result<GraphSettings, V::Error>
where
V: MapAccess<'de>,
{
let mut run_args = None;
let mut num_rows = None;
let mut total_assignments = None;
let mut total_const_size = None;
let mut total_dynamic_col_size = None;
let mut max_dynamic_input_len = None;
let mut num_dynamic_lookups = None;
let mut num_shuffles = None;
let mut total_shuffle_col_size = None;
let mut model_instance_shapes = None;
let mut model_output_scales = None;
let mut model_input_scales = None;
let mut module_sizes = None;
let mut required_lookups = None;
let mut required_range_checks = None;
let mut check_mode = None;
let mut version = None;
let mut num_blinding_factors = None;
let mut timestamp = None;
let mut input_types = None;
let mut output_types = None;
while let Some(key) = map.next_key()? {
match key {
Field::RunArgs => {
if run_args.is_some() {
return Err(de::Error::duplicate_field("run_args"));
}
run_args = Some(map.next_value()?);
}
Field::NumRows => {
if num_rows.is_some() {
return Err(de::Error::duplicate_field("num_rows"));
}
num_rows = Some(map.next_value()?);
}
Field::TotalAssignments => {
if total_assignments.is_some() {
return Err(de::Error::duplicate_field("total_assignments"));
}
total_assignments = Some(map.next_value()?);
}
Field::TotalConstSize => {
if total_const_size.is_some() {
return Err(de::Error::duplicate_field("total_const_size"));
}
total_const_size = Some(map.next_value()?);
}
Field::TotalDynamicColSize => {
if total_dynamic_col_size.is_some() {
return Err(de::Error::duplicate_field("total_dynamic_col_size"));
}
total_dynamic_col_size = Some(map.next_value()?);
}
Field::MaxDynamicInputLen => {
if max_dynamic_input_len.is_some() {
return Err(de::Error::duplicate_field("max_dynamic_input_len"));
}
max_dynamic_input_len = Some(map.next_value()?);
}
Field::NumDynamicLookups => {
if num_dynamic_lookups.is_some() {
return Err(de::Error::duplicate_field("num_dynamic_lookups"));
}
num_dynamic_lookups = Some(map.next_value()?);
}
Field::NumShuffles => {
if num_shuffles.is_some() {
return Err(de::Error::duplicate_field("num_shuffles"));
}
num_shuffles = Some(map.next_value()?);
}
Field::TotalShuffleColSize => {
if total_shuffle_col_size.is_some() {
return Err(de::Error::duplicate_field("total_shuffle_col_size"));
}
total_shuffle_col_size = Some(map.next_value()?);
}
Field::ModelInstanceShapes => {
if model_instance_shapes.is_some() {
return Err(de::Error::duplicate_field("model_instance_shapes"));
}
model_instance_shapes = Some(map.next_value()?);
}
Field::ModelOutputScales => {
if model_output_scales.is_some() {
return Err(de::Error::duplicate_field("model_output_scales"));
}
model_output_scales = Some(map.next_value()?);
}
Field::ModelInputScales => {
if model_input_scales.is_some() {
return Err(de::Error::duplicate_field("model_input_scales"));
}
model_input_scales = Some(map.next_value()?);
}
Field::ModuleSizes => {
if module_sizes.is_some() {
return Err(de::Error::duplicate_field("module_sizes"));
}
module_sizes = Some(map.next_value()?);
}
Field::RequiredLookups => {
if required_lookups.is_some() {
return Err(de::Error::duplicate_field("required_lookups"));
}
required_lookups = Some(map.next_value()?);
}
Field::RequiredRangeChecks => {
if required_range_checks.is_some() {
return Err(de::Error::duplicate_field("required_range_checks"));
}
required_range_checks = Some(map.next_value()?);
}
Field::CheckMode => {
if check_mode.is_some() {
return Err(de::Error::duplicate_field("check_mode"));
}
check_mode = Some(map.next_value()?);
}
Field::Version => {
if version.is_some() {
return Err(de::Error::duplicate_field("version"));
}
version = Some(map.next_value()?);
}
Field::NumBlindingFactors => {
if num_blinding_factors.is_some() {
return Err(de::Error::duplicate_field("num_blinding_factors"));
}
num_blinding_factors = map.next_value()?;
}
Field::Timestamp => {
if timestamp.is_some() {
return Err(de::Error::duplicate_field("timestamp"));
}
timestamp = Some(map.next_value()?);
}
Field::InputTypes => {
if input_types.is_some() {
return Err(de::Error::duplicate_field("input_types"));
}
input_types = map.next_value()?;
}
Field::OutputTypes => {
if output_types.is_some() {
return Err(de::Error::duplicate_field("output_types"));
}
output_types = map.next_value()?;
}
// Handle legacy nested struct fields for backwards compatibility
Field::DynamicLookupParams => {
let legacy_params: DynamicLookupParams = map.next_value()?;
if total_dynamic_col_size.is_none() {
total_dynamic_col_size = Some(legacy_params.total_dynamic_col_size);
}
if max_dynamic_input_len.is_none() {
max_dynamic_input_len = Some(legacy_params.max_dynamic_input_len);
}
if num_dynamic_lookups.is_none() {
num_dynamic_lookups = Some(legacy_params.num_dynamic_lookups);
}
}
Field::ShuffleParams => {
let legacy_params: ShuffleParams = map.next_value()?;
if num_shuffles.is_none() {
num_shuffles = Some(legacy_params.num_shuffles);
}
if total_shuffle_col_size.is_none() {
total_shuffle_col_size = Some(legacy_params.total_shuffle_col_size);
}
}
}
}
let run_args = run_args.ok_or_else(|| de::Error::missing_field("run_args"))?;
let num_rows = num_rows.ok_or_else(|| de::Error::missing_field("num_rows"))?;
let total_assignments = total_assignments
.ok_or_else(|| de::Error::missing_field("total_assignments"))?;
let total_const_size =
total_const_size.ok_or_else(|| de::Error::missing_field("total_const_size"))?;
let model_instance_shapes = model_instance_shapes
.ok_or_else(|| de::Error::missing_field("model_instance_shapes"))?;
let model_output_scales = model_output_scales
.ok_or_else(|| de::Error::missing_field("model_output_scales"))?;
let model_input_scales = model_input_scales
.ok_or_else(|| de::Error::missing_field("model_input_scales"))?;
let module_sizes =
module_sizes.ok_or_else(|| de::Error::missing_field("module_sizes"))?;
let required_lookups =
required_lookups.ok_or_else(|| de::Error::missing_field("required_lookups"))?;
let required_range_checks = required_range_checks
.ok_or_else(|| de::Error::missing_field("required_range_checks"))?;
let check_mode =
check_mode.ok_or_else(|| de::Error::missing_field("check_mode"))?;
let version = version.ok_or_else(|| de::Error::missing_field("version"))?;
// Build the nested structs from flattened fields, with defaults if missing
let dynamic_lookup_params = DynamicLookupParams {
total_dynamic_col_size: total_dynamic_col_size.unwrap_or_default(),
max_dynamic_input_len: max_dynamic_input_len.unwrap_or_default(),
num_dynamic_lookups: num_dynamic_lookups.unwrap_or_default(),
};
let shuffle_params = ShuffleParams {
num_shuffles: num_shuffles.unwrap_or_default(),
total_shuffle_col_size: total_shuffle_col_size.unwrap_or_default(),
};
Ok(GraphSettings {
run_args,
num_rows,
total_assignments,
total_const_size,
dynamic_lookup_params,
shuffle_params,
model_instance_shapes,
model_output_scales,
model_input_scales,
module_sizes,
required_lookups,
required_range_checks,
check_mode,
version,
num_blinding_factors,
timestamp,
input_types,
output_types,
})
}
fn visit_seq<V>(self, mut seq: V) -> Result<GraphSettings, V::Error>
where
V: serde::de::SeqAccess<'de>,
{
use serde::de::Error;
// For bincode compatibility, deserialize in the same order as tuple serialization
let run_args = seq.next_element()?.ok_or_else(|| Error::invalid_length(0, &self))?;
let num_rows = seq.next_element()?.ok_or_else(|| Error::invalid_length(1, &self))?;
let total_assignments = seq.next_element()?.ok_or_else(|| Error::invalid_length(2, &self))?;
let total_const_size = seq.next_element()?.ok_or_else(|| Error::invalid_length(3, &self))?;
let dynamic_lookup_params = seq.next_element()?.ok_or_else(|| Error::invalid_length(4, &self))?;
let shuffle_params = seq.next_element()?.ok_or_else(|| Error::invalid_length(5, &self))?;
let model_instance_shapes = seq.next_element()?.ok_or_else(|| Error::invalid_length(6, &self))?;
let model_output_scales = seq.next_element()?.ok_or_else(|| Error::invalid_length(7, &self))?;
let model_input_scales = seq.next_element()?.ok_or_else(|| Error::invalid_length(8, &self))?;
let module_sizes = seq.next_element()?.ok_or_else(|| Error::invalid_length(9, &self))?;
let required_lookups = seq.next_element()?.ok_or_else(|| Error::invalid_length(10, &self))?;
let required_range_checks = seq.next_element()?.ok_or_else(|| Error::invalid_length(11, &self))?;
let check_mode = seq.next_element()?.ok_or_else(|| Error::invalid_length(12, &self))?;
let version = seq.next_element()?.ok_or_else(|| Error::invalid_length(13, &self))?;
let num_blinding_factors = seq.next_element()?.ok_or_else(|| Error::invalid_length(14, &self))?;
let timestamp = seq.next_element()?.ok_or_else(|| Error::invalid_length(15, &self))?;
let input_types = seq.next_element()?.ok_or_else(|| Error::invalid_length(16, &self))?;
let output_types = seq.next_element()?.ok_or_else(|| Error::invalid_length(17, &self))?;
Ok(GraphSettings {
run_args,
num_rows,
total_assignments,
total_const_size,
dynamic_lookup_params,
shuffle_params,
model_instance_shapes,
model_output_scales,
model_input_scales,
module_sizes,
required_lookups,
required_range_checks,
check_mode,
version,
num_blinding_factors,
timestamp,
input_types,
output_types,
})
}
}
// Universal deserializer that works with both JSON (map) and bincode (tuple)
if deserializer.is_human_readable() {
// JSON format - use struct/map deserialization with flattened fields
const FIELDS: &'static [&'static str] = &[
"run_args", "num_rows", "total_assignments", "total_const_size",
"total_dynamic_col_size", "max_dynamic_input_len", "num_dynamic_lookups",
"num_shuffles", "total_shuffle_col_size", "model_instance_shapes",
"model_output_scales", "model_input_scales", "module_sizes",
"required_lookups", "required_range_checks", "check_mode", "version",
"num_blinding_factors", "timestamp", "input_types", "output_types",
"dynamic_lookup_params", "shuffle_params",
];
deserializer.deserialize_struct("GraphSettings", FIELDS, GraphSettingsVisitor)
} else {
// Binary format (bincode) - use tuple deserialization
deserializer.deserialize_tuple(18, GraphSettingsVisitor)
}
}
}
impl GraphSettings {
/// Calc the number of rows required for lookup tables
pub fn lookup_log_rows(&self) -> u32 {
@@ -1674,3 +2104,155 @@ impl Circuit<Fp> for GraphCircuit {
Ok(())
}
}
#[cfg(test)]
/// Tests for the graph module
pub mod tests {
use super::*;
#[test]
fn test_graph_settings_serialization_roundtrip() {
use crate::{CheckMode, RunArgs};
// Create a test GraphSettings with nested structs
let original = GraphSettings {
run_args: RunArgs::default(),
num_rows: 1000,
total_assignments: 500,
total_const_size: 100,
dynamic_lookup_params: DynamicLookupParams {
total_dynamic_col_size: 42,
max_dynamic_input_len: 128,
num_dynamic_lookups: 5,
},
shuffle_params: ShuffleParams {
num_shuffles: 3,
total_shuffle_col_size: 256,
},
model_instance_shapes: vec![vec![1, 2, 3]],
model_output_scales: vec![],
model_input_scales: vec![],
module_sizes: ModuleSizes::default(),
required_lookups: vec![],
required_range_checks: vec![],
check_mode: CheckMode::SAFE,
version: "1.0.0".to_string(),
num_blinding_factors: Some(5),
timestamp: Some(123456789),
input_types: None,
output_types: None,
};
// Test 1: JSON serialization roundtrip with flattened format
let json_str = serde_json::to_string_pretty(&original).unwrap();
println!("JSON serialized (flattened):\n{}", json_str);
// Verify the JSON contains flattened fields
assert!(json_str.contains("\"total_dynamic_col_size\": 42"));
assert!(json_str.contains("\"max_dynamic_input_len\": 128"));
assert!(json_str.contains("\"num_dynamic_lookups\": 5"));
assert!(json_str.contains("\"num_shuffles\": 3"));
assert!(json_str.contains("\"total_shuffle_col_size\": 256"));
// Verify the JSON does NOT contain nested structs
assert!(!json_str.contains("\"dynamic_lookup_params\""));
assert!(!json_str.contains("\"shuffle_params\""));
// Deserialize from JSON
let deserialized: GraphSettings = serde_json::from_str(&json_str).unwrap();
assert_eq!(original, deserialized);
// now do JSON bytes
let json_bytes = serde_json::to_vec(&original).unwrap();
let deserialized_from_bytes: GraphSettings = serde_json::from_slice(&json_bytes).unwrap();
assert_eq!(original, deserialized_from_bytes);
// Test 2: Bincode serialization roundtrip
let bincode_data = bincode::serialize(&original).unwrap();
let bincode_deserialized: GraphSettings = bincode::deserialize(&bincode_data).unwrap();
assert_eq!(original, bincode_deserialized);
// Test 3: Backwards compatibility - deserialize old nested format
let old_format_json = r#"{
"run_args": {
"tolerance": {
"val": 0.0,
"scale": 1.0
},
"input_scale": 0,
"param_scale": 0,
"scale_rebase_multiplier": 10,
"lookup_range": [
0,
0
],
"logrows": 6,
"num_inner_cols": 2,
"variables": [
[
"batch_size",
1
]
],
"input_visibility": "Private",
"output_visibility": "Public",
"param_visibility": "Private",
"rebase_frac_zero_constants": false,
"check_mode": "UNSAFE",
"commitment": "KZG",
"decomp_base": 128,
"decomp_legs": 2,
"bounded_log_lookup": false,
"ignore_range_check_inputs_outputs": false
},
"num_rows": 236,
"total_assignments": 472,
"total_const_size": 4,
"total_dynamic_col_size": 0,
"max_dynamic_input_len": 0,
"num_dynamic_lookups": 0,
"num_shuffles": 0,
"total_shuffle_col_size": 0,
"model_instance_shapes": [
[
1,
4
]
],
"model_output_scales": [
0
],
"model_input_scales": [
0
],
"module_sizes": {
"polycommit": [],
"poseidon": [
0,
[
0
]
]
},
"required_lookups": [],
"required_range_checks": [
[
-1,
1
],
[
0,
127
]
],
"check_mode": "UNSAFE",
"version": "0.0.0",
"num_blinding_factors": null,
"timestamp": 1741214578354
}"#;
let _backwards_compatible: GraphSettings = serde_json::from_str(old_format_json).unwrap();
}
}

View File

@@ -9,7 +9,7 @@ use itertools::Itertools;
use log::debug;
#[cfg(feature = "python-bindings")]
use pyo3::{
exceptions::PyValueError, FromPyObject, IntoPy, PyObject, PyResult, Python, ToPyObject,
exceptions::PyValueError, FromPyObject, IntoPyObject, PyResult, Python,
};
use serde::{Deserialize, Serialize};
#[cfg(all(feature = "ezkl", not(target_arch = "wasm32")))]
@@ -107,27 +107,31 @@ impl<'a> From<&'a str> for Visibility {
}
#[cfg(feature = "python-bindings")]
impl IntoPy<PyObject> for Visibility {
impl<'py> IntoPyObject<'py> for Visibility {
type Target = pyo3::PyAny;
type Output = pyo3::Bound<'py, Self::Target>;
type Error = pyo3::PyErr;
/// Converts Visibility to Python object
fn into_py(self, py: Python) -> PyObject {
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
match self {
Visibility::Private => "private".to_object(py),
Visibility::Public => "public".to_object(py),
Visibility::Fixed => "fixed".to_object(py),
Visibility::KZGCommit => "polycommit".to_object(py),
Visibility::Private => Ok("private".into_pyobject(py)?.into_any()),
Visibility::Public => Ok("public".into_pyobject(py)?.into_any()),
Visibility::Fixed => Ok("fixed".into_pyobject(py)?.into_any()),
Visibility::KZGCommit => Ok("polycommit".into_pyobject(py)?.into_any()),
Visibility::Hashed {
hash_is_public,
outlets,
} => {
if hash_is_public {
"hashed/public".to_object(py)
Ok("hashed/public".into_pyobject(py)?.into_any())
} else {
let outlets = outlets
.iter()
.map(|o| o.to_string())
.collect_vec()
.join(",");
format!("hashed/private/{}", outlets).to_object(py)
Ok(format!("hashed/private/{}", outlets).into_pyobject(py)?.into_any())
}
}
}

View File

@@ -187,12 +187,17 @@ impl From<ProofType> for StrategyType {
}
#[cfg(feature = "python-bindings")]
impl ToPyObject for ProofType {
fn to_object(&self, py: Python) -> PyObject {
match self {
ProofType::Single => "Single".to_object(py),
ProofType::ForAggr => "ForAggr".to_object(py),
}
impl<'py> pyo3::IntoPyObject<'py> for ProofType {
type Target = pyo3::PyAny;
type Output = pyo3::Bound<'py, Self::Target>;
type Error = pyo3::PyErr;
fn into_pyobject(self, py: pyo3::Python<'py>) -> Result<Self::Output, Self::Error> {
let result = match self {
ProofType::Single => "Single",
ProofType::ForAggr => "ForAggr",
};
Ok(result.into_pyobject(py)?.into_any())
}
}
@@ -245,12 +250,17 @@ impl std::fmt::Display for StrategyType {
}
#[cfg(feature = "python-bindings")]
/// Converts StrategyType into a PyObject (Required for StrategyType to be compatible with Python)
impl pyo3::IntoPy<PyObject> for StrategyType {
fn into_py(self, py: Python) -> PyObject {
match self {
StrategyType::Single => "single".to_object(py),
StrategyType::Accum => "accum".to_object(py),
}
impl<'py> pyo3::IntoPyObject<'py> for StrategyType {
type Target = pyo3::PyAny;
type Output = pyo3::Bound<'py, Self::Target>;
type Error = pyo3::PyErr;
fn into_pyobject(self, py: pyo3::Python<'py>) -> Result<Self::Output, Self::Error> {
let result = match self {
StrategyType::Single => "single",
StrategyType::Accum => "accum",
};
Ok(result.into_pyobject(py)?.into_any())
}
}
#[cfg(feature = "python-bindings")]
@@ -304,15 +314,6 @@ impl ToFlags for TranscriptType {
}
}
#[cfg(feature = "python-bindings")]
impl ToPyObject for TranscriptType {
fn to_object(&self, py: Python) -> PyObject {
match self {
TranscriptType::Poseidon => "Poseidon".to_object(py),
TranscriptType::EVM => "EVM".to_object(py),
}
}
}
#[cfg(feature = "python-bindings")]
///
@@ -401,14 +402,18 @@ where
}
#[cfg(feature = "python-bindings")]
use pyo3::{types::PyDict, PyObject, Python, ToPyObject};
use pyo3::{types::PyDict, IntoPyObject, Python};
#[cfg(feature = "python-bindings")]
impl<F: PrimeField + SerdeObject + Serialize, C: CurveAffine + Serialize> ToPyObject for Snark<F, C>
impl<'py, F: PrimeField + SerdeObject + Serialize, C: CurveAffine + Serialize> IntoPyObject<'py> for Snark<F, C>
where
C::Scalar: Serialize + DeserializeOwned,
C::ScalarExt: Serialize + DeserializeOwned,
{
fn to_object(&self, py: Python) -> PyObject {
type Target = pyo3::PyAny;
type Output = pyo3::Bound<'py, Self::Target>;
type Error = pyo3::PyErr;
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
let dict = PyDict::new(py);
let field_elems: Vec<Vec<String>> = self
.instances
@@ -418,9 +423,9 @@ 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.to_object(py))
dict.set_item("transcript_type", self.transcript_type.into_pyobject(py)?)
.unwrap();
dict.to_object(py)
Ok(dict.into_any())
}
}

Binary file not shown.

View File

@@ -163,9 +163,12 @@ mod native_tests {
let data = GraphData::from_path(format!("{}/{}/input.json", test_dir, test).into())
.expect("failed to load input data");
let duplicated_input_data = data.input_data;
let duplicated_input_data = data.input_data.into_iter().map(|input| {
(0..num_batches)
.map(move |_| input.clone()).flatten().collect::<Vec<_>>()
}).collect::<Vec<_>>();
let duplicated_data = GraphData::new(duplicated_input_data.into());
let duplicated_data = GraphData::new(duplicated_input_data);
let res =
duplicated_data.save(format!("{}/{}/input.json", test_dir, output_dir).into());
@@ -2238,6 +2241,7 @@ mod native_tests {
assert!(status.success());
}
#[allow(unused_variables)]
fn build_ezkl() {
#[cfg(feature = "icicle")]
let args = [