Skip to content

feat: add e3-noir-prover crate for proof generation [skip-line-limit]#1211

Merged
ctrlc03 merged 45 commits into
mainfrom
feat/noir-prover
Feb 9, 2026
Merged

feat: add e3-noir-prover crate for proof generation [skip-line-limit]#1211
ctrlc03 merged 45 commits into
mainfrom
feat/noir-prover

Conversation

@hmzakhalid

@hmzakhalid hmzakhalid commented Jan 27, 2026

Copy link
Copy Markdown
Collaborator

Enable ciphernodes to generate proofs for cryptographic operations (key generation, decryption shares, etc.) using Noir circuits and the Barretenberg prover.

High-Level Flow

1. Ciphernode receives CiphernodeSelected event
                    │
                    ▼
2. Generate BFV key pair (existing FHE logic)
                    │
                    ▼
3. Prepare circuit inputs (serialize to TOML)
                    │
                    ▼
4. Call NoirProver::generate_proof()
         │
         ├── Create work dir: ~/.enclave/noir/work/<e3_id>/
         │
         ├── Write inputs to ~/.enclave/noir/work/<e3_id>/inputs.toml
         │
         ├── Execute: bb prove --scheme ultra_honk \
         │              -b ~/.enclave/noir/circuits/pk_bfv.json \
         │              -w ~/.enclave/noir/work/<e3_id>/witness.gz \
         │              -o ~/.enclave/noir/work/<e3_id>/
         │
         └── Read proof from output file
                 │
                ▼
5. Broadcast KeyshareCreated { pubkey, proof_0, ... }
                 │
                ▼
6. Cleanup work directory (witness stays local, never transferred)

Enclave Noir CLI

Noir prover management and proof generation

Usage: enclave noir [OPTIONS] <COMMAND>

Commands:
  status  Check Noir prover setup status (bb binary and circuits)
  setup   Download or update bb binary and circuit artifacts
  prove   Generate a proof for a circuit (for testing)
  verify  Verify a proof (for testing)
  help    Print this message or the help of the given subcommand(s)

Directory Structure

~/.enclave/
└── noir/
    ├── version.json           # Tracks binary versions
    ├── bin/
    │   └── bb                  
    ├── circuits/               # Pre-compiled circuit artifacts
    │   ├── pk_bfv.json         # T0: BFV public key generation circuit
    │   ├── dec_share_trbfv.json # Decryption share circuit
    │   ├── verify_shares.json  # Share verification circuit
    │   └── vk/                 # Verification keys
    │       ├── pk_bfv.vk
    │       └── ...
    └── work/                   # Runtime working directory
        └── <e3_id>/            # Per-request working directory
            ├── inputs.toml     # Circuit inputs 
            ├── witness.gz      # Generated witness 
            └── proof           # Generated proof 

Remaining Tasks:

  • Pin exact bb version and add checksum verification
  • Set up circuit artifact hosting on GitHub Releases and update download URLs
  • Implement T0 proof generation
    • Map BFV key generation outputs to circuit inputs
    • Generate Proof 0 when creating BFV key pair
    • Create/cleanup ~/.enclave/noir/work/<e3_id>/
    • Include Proof 0 in KeyshareCreated message
    • Verify received Proof 0 before accepting pubkey
    • E2E tests with T0 proof generation and verification
  • Bundle bb binary in Docker image for production deployments
  • Add benchmarks for proof generation time and memory usage
  • E2E tests with multiple ciphernodes exchanging proofs

Summary by CodeRabbit

  • New Features
    • Full ZK prover added: CLI noir commands (status/setup), prover backend, actors for proof generation & verification, and optional ZK integration in node builder/runtime.
  • Bug Fixes
    • Encryption key flow updated to emit pending/received events and verify ZK proofs before finalizing keys.
  • Chores
    • Workspace manifests, CI, startup scripts and templates updated to provision the ZK prover.
  • Tests
    • Extensive unit, integration, local e2e and backend tests for prover, witness, and verification flows.

@vercel

vercel Bot commented Jan 27, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
crisp Ready Ready Preview, Comment Feb 6, 2026 6:58pm
enclave-docs Ready Ready Preview, Comment Feb 6, 2026 6:58pm

Request Review

@coderabbitai

coderabbitai Bot commented Jan 27, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Adds a new crates/zk-prover crate and integrates zero-knowledge proof generation/verification across the workspace: new ZK backend, prover, actors, events (TrBFV / Zk), BFV preset changes, CLI noir commands, CI/scripts updates, and wiring into multithread, keyshare, aggregator, ciphernode-builder, net, and entrypoint.

Changes

Cohort / File(s) Summary
ZK prover core
crates/zk-prover/Cargo.toml, crates/zk-prover/src/lib.rs, crates/zk-prover/src/error.rs, crates/zk-prover/src/config.rs, crates/zk-prover/src/prover.rs, crates/zk-prover/src/traits.rs, crates/zk-prover/src/witness.rs, crates/zk-prover/src/circuits/*, crates/zk-prover/tests/*, crates/zk-prover/versions.json
Add new e3-zk-prover crate: ZkBackend, ZkProver, ZkError, Provable trait, witness/circuit implementations, config/version handling, download/setup, fixtures and tests.
Actors & integration
crates/zk-prover/src/actors/*, crates/multithread/src/multithread.rs, crates/ciphernode-builder/src/ciphernode_builder.rs, crates/entrypoint/src/start/start.rs
Add ProofRequestActor, ProofVerificationActor, ZkActor; Multithread and CiphernodeBuilder gain optional ZK wiring; entrypoint initializes ZkBackend and calls ensure_installed.
Events & compute protocol
crates/events/src/enclave_event/compute_request/mod.rs, crates/events/src/enclave_event/compute_request/zk.rs, crates/events/src/enclave_event/proof.rs, crates/events/src/enclave_event/encryption_key_*.rs, crates/events/src/enclave_event/mod.rs
Introduce protocol-discriminated ComputeRequestKind/ComputeResponseKind (TrBFV / Zk), add Zk request/response/error types, Proof/CircuitName, and new encryption-key events (EncryptionKeyPending, EncryptionKeyReceived).
Keyshare / aggregator / trbfv
crates/keyshare/src/threshold_keyshare.rs, crates/aggregator/src/threshold_plaintext_aggregator.rs, crates/keyshare/src/ext.rs
Switch compute request construction to protocol-specific APIs and response matching to ComputeResponseKind; emit EncryptionKeyPending instead of immediate created; migrate share encryption param handling to BfvPreset-based presets.
BFV presets & helpers
crates/fhe-params/src/presets.rs, crates/trbfv/src/helpers.rs, crates/trbfv/src/shares/bfv_encrypted.rs, crates/test-helpers/src/usecase_helpers.rs
Add serde derives and threshold_counterpart to BfvPreset; remove get_share_encryption_params helper and update call sites to use BfvParamSet/BfvPreset.
CLI & tooling
crates/cli/src/noir.rs, crates/cli/src/cli.rs, crates/cli/src/main.rs, crates/cli/Cargo.toml
Add noir CLI subcommand with Status/Setup to inspect/install Barretenberg and circuits via ZkBackend; add workspace deps.
Net / document publish
crates/net/src/document_publisher.rs
DocumentReceived path now publishes EncryptionKeyReceived for externally sourced keys to trigger verification flow rather than publishing created keys immediately.
Workspace & manifests
top-level Cargo.toml, various crates/*/Cargo.toml (cli, ciphernode-builder, multithread, keyshare, events, entrypoint, zk-helpers, fhe-params, ...)
Add e3-zk-prover workspace crate and update workspace dependency entries (toml, e3-fhe-params, e3-zk-helpers, etc.).
CI, scripts, Docker
.github/workflows/ci.yml, crates/Dockerfile, templates/.../dev_ciphernodes.sh, tests/integration/*.sh, examples/CRISP/scripts/dev_cipher.sh
Add zk_prover_integration CI job; insert enclave noir setup steps in CI and developer scripts; Dockerfile copies zk-prover Cargo.toml into build context.
Misc / lint/test fixes
small updates (crates/evm/src/*.rs, crates/sync/src/sync.rs, crates/config/*, tests, artifacts/deployed_contracts.json)`
Minor lint/import renames, test import reorganizations, artifact/deployment JSON additions and test updates.

Sequence Diagram(s)

sequenceDiagram
    participant KS as ThresholdKeyshare
    participant PRA as ProofRequestActor
    participant MT as Multithread
    participant ZK as ZkProver
    participant BB as Barretenberg

    KS->>PRA: EncryptionKeyPending(e3_id, key, preset)
    activate PRA
    PRA->>PRA: create CorrelationId & store pending
    PRA->>MT: publish ComputeRequest::zk(PkBfvProofRequest, corr_id)
    activate MT
    MT->>ZK: handle_zk_request(PkBfvProofRequest)
    activate ZK
    ZK->>ZK: build witness from PublicKey
    ZK->>BB: run Barretenberg to generate proof
    BB-->>ZK: proof + public_signals
    ZK-->>MT: ComputeResponse::zk(PkBfvProofResponse, corr_id)
    MT-->>PRA: ComputeResponse with proof
    PRA->>PRA: match correlation_id, attach proof to key
    PRA->>KS: publish EncryptionKeyCreated(e3_id, key+proof)
    deactivate PRA
Loading
sequenceDiagram
    participant Net as DocumentPublisher
    participant PVA as ProofVerificationActor
    participant ZKA as ZkActor
    participant ZK as ZkProver
    participant BB as Barretenberg

    Net->>PVA: EncryptionKeyReceived(e3_id, key+proof)
    activate PVA
    alt verifier available
        PVA->>ZKA: ZkVerificationRequest(proof, key, e3_id)
        activate ZKA
        ZKA->>ZK: verify_proof(circuit, proof_data, public_signals)
        activate ZK
        ZK->>BB: verify proof
        BB-->>ZK: verification result
        ZK-->>ZKA: boolean result
        ZKA-->>PVA: ZkVerificationResponse(verified, e3_id, key)
        alt verified
            PVA->>Net: publish EncryptionKeyCreated(external: true)
        else failed
            PVA->>PVA: log error, do not publish
        end
        deactivate ZKA
    else no verifier
        PVA->>Net: publish EncryptionKeyCreated(external: true)
    end
    deactivate PVA
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

Suggested labels

ciphernode

Suggested reviewers

  • ctrlc03

Poem

🐰 I hopped through crates and cargo trees,

I stitched proofs from keys and tiny cheese,
Barretenberg hummed, witness bytes anew,
Correlation matched — one request, one view.
The rabbit cheered: "Proofs are now for you!"

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 44.65% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding a new e3-noir-prover crate for proof generation, which is the primary feature in this changeset.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/noir-prover

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@hmzakhalid hmzakhalid changed the title feat: add e3-noir-prover crate for Noir proof generation feat: add e3-noir-prover crate for Noir proof generation [skip-line-limit] Jan 27, 2026
@hmzakhalid hmzakhalid changed the title feat: add e3-noir-prover crate for Noir proof generation [skip-line-limit] feat: add e3-noir-prover crate for proof generation [skip-line-limit] Jan 27, 2026
@ctrlc03 ctrlc03 self-requested a review January 28, 2026 14:42
@ctrlc03 ctrlc03 requested a review from ryardley January 28, 2026 14:58
@github-actions

Copy link
Copy Markdown
Contributor

License Header Check Failed

Some files are missing the required SPDX license header. Please add the following header to the beginning of all .js, .jsx, .nr, .rs, .sol, .ts, and .tsx files:

// SPDX-License-Identifier: LGPL-3.0-only
//
// This file is provided WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE.

You can run ./scripts/check-license-headers.sh --fix locally to automatically add missing headers, then commit the changes.

Or run ./scripts/check-license-headers.sh to see which files need headers.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Fix all issues with AI agents
In `@crates/ciphernode-builder/src/ciphernode_builder.rs`:
- Around line 423-435: The code currently hardcodes BfvPreset::InsecureDkg512
when creating ThresholdKeyshareExtension (see BfvPreset::InsecureDkg512 and
ThresholdKeyshareExtension::create in ciphernode_builder.rs), which is unsafe
for production; either add a clear TODO comment next to that line documenting
the planned migration to secure parameters (e.g., BfvPreset::SecureDkg8192) or,
preferably, make the preset configurable by adding a builder method (e.g.,
with_share_enc_preset(BfvPreset)) on the same builder that provides
with_zkproof(), store the chosen preset in self, and replace the hardcoded
BfvPreset::InsecureDkg512 with that field when calling
ThresholdKeyshareExtension::create.

In `@crates/cli/src/noir.rs`:
- Around line 111-134: The force flag is ignored in execute_setup: when force is
true you print "Force reinstalling..." but then call ZkBackend::ensure_installed
which currently bails out if SetupStatus::Ready; either modify ensure_installed
to accept a force: bool parameter and pass force from execute_setup (update its
signature and internal logic to skip the readiness short-circuit when
force==true), or bypass ensure_installed in the force branch and call
ZkBackend::download_bb() and ZkBackend::download_circuits() (and any other
install steps) directly from execute_setup; locate these by the function names
execute_setup, ensure_installed, download_bb, download_circuits and update the
caller and/or callee accordingly so a true force actually reinstalls.

In `@crates/multithread/src/multithread.rs`:
- Around line 342-343: The comment is misleading and the code uses
BfvParamSet::from(req.params_preset.clone()).build_arc() without ensuring the
preset is a DKG preset; either update the comment to state that
req.params_preset MUST be a DKG preset or add runtime validation that rejects
non-DKG presets before building params (e.g., check the preset kind or that its
threshold_counterpart() exists/returns the expected DKG variant) and return an
error if validation fails so subsequent use of params (and any
threshold_counterpart() calls) is correct; locate the logic around
BfvParamSet::from and req.params_preset to add the validation or change the
comment accordingly.

In `@crates/zk-prover/src/actors/proof_request.rs`:
- Around line 112-120: The handler handle_compute_request_error currently
removes the pending entry for a failed ComputeRequestError (matching
ComputeRequestErrorKind::Zk) and only logs a warning, which leaves downstream
actors waiting; change it to publish an error event or a fallback
EncryptionKeyCreated so the pipeline continues: after detecting the ZK error and
removing self.pending (using msg.correlation_id()), call the event-bus publish
method (e.g., bus.err(...) with the error and correlation id) or publish an
EncryptionKeyCreated for that node without a proof (populate the same
correlation id and node id from the pending entry) so consumers receive a
terminal event; ensure you reference ComputeRequestError,
ComputeRequestErrorKind::Zk, handle_compute_request_error, self.pending, and
EncryptionKeyCreated when making the change.

In `@crates/zk-prover/src/backend/mod.rs`:
- Around line 65-67: The function work_dir_for currently joins an unsanitized
e3_id into the path (unlike cleanup_work_dir which validates first); move the
sanitization/validation into work_dir_for (or extract a shared helper like
validate_e3_id) and have work_dir_for call that helper to reject or normalize
unsafe inputs (e.g., disallow path separators, empty strings, .., or invalid
characters) before doing self.work_dir.join(sanitized_e3_id); update callers
(including cleanup_work_dir) to use the new helper/work_dir_for so all call
sites get the same protection.
🧹 Nitpick comments (28)
crates/Dockerfile (2)

68-68: Nit: zk-prover COPY is out of alphabetical order.

All other COPY lines in this block follow roughly alphabetical order. zk-prover should be placed after zk-helpers (Line 83) to stay consistent.

 COPY crates/parity-matrix/Cargo.toml ./parity-matrix/Cargo.toml
-COPY crates/zk-prover/Cargo.toml ./zk-prover/Cargo.toml
 COPY crates/polynomial/Cargo.toml ./polynomial/Cargo.toml
 ...
 COPY crates/zk-helpers/Cargo.toml ./zk-helpers/Cargo.toml
+COPY crates/zk-prover/Cargo.toml ./zk-prover/Cargo.toml

110-139: Runtime stage does not include the bb (Barretenberg) binary.

The PR objectives note "bundle bb binary in Docker for production" as a remaining task. Currently the runtime image has no bb binary, no circuit artifacts under ~/.enclave/noir/, and no download step — so ZK proof generation will fail at runtime in Docker. Just flagging this as a reminder since it's already tracked.

crates/cli/Cargo.toml (1)

27-27: Nit: e3-zk-prover should come after e3-support-scripts alphabetically.

 e3-init = { workspace = true }
-e3-zk-prover = { workspace = true }
 e3-support-scripts = { workspace = true }
+e3-zk-prover = { workspace = true }
crates/fhe-params/src/presets.rs (1)

314-326: Clean inverse of dkg_counterpart — consider adding a unit test.

The mapping is correct and symmetric with dkg_counterpart. A small round-trip test would lock in the invariant that preset.dkg_counterpart().and_then(|d| d.threshold_counterpart()) == Some(preset) for threshold presets (and vice-versa).

💡 Optional test for symmetry
#[test]
fn threshold_dkg_counterparts_are_symmetric() {
    for preset in BfvPreset::PAIR_PRESETS {
        let dkg = preset.dkg_counterpart().expect("pair preset has DKG counterpart");
        assert_eq!(dkg.threshold_counterpart(), Some(preset));
    }
}
crates/zk-prover/src/error.rs (2)

63-64: Nit: inconsistent error message capitalization.

"checksum missing for {0}" starts lowercase while all other variants use sentence-case (e.g., "Checksum mismatch for {file}").

Proposed fix
-    #[error("checksum missing for {0}")]
+    #[error("Checksum missing for {0}")]

51-52: TomlError only covers serialization errors; consider adding deserialization support if TOML reading is added later.

The #[from] conversion is for toml::ser::Error only. Currently the crate only serializes TOML (inputs.toml), so this works. If the crate evolves to read/parse TOML files, you'll need to handle toml::de::Error separately or add another variant.

crates/zk-prover/src/prover.rs (2)

31-37: Consider returning &Path instead of &PathBuf.

Idiomatic Rust prefers returning &Path from accessors since PathBuf auto-derefs to Path, and &Path is the more general borrowed form.

♻️ Suggested change
-    pub fn circuits_dir(&self) -> &PathBuf {
+    pub fn circuits_dir(&self) -> &std::path::Path {
         &self.circuits_dir
     }
 
-    pub fn work_dir(&self) -> &PathBuf {
+    pub fn work_dir(&self) -> &std::path::Path {
         &self.work_dir
     }

205-219: Unit test coverage is minimal.

There is only one test (test_prover_requires_bb), which validates a single error path. Consider adding tests for other validation paths (e.g., missing circuit file, missing VK file) that don't require a real bb binary.

crates/zk-prover/tests/fixtures/pk.json (1)

1-65: Large compiled circuit fixture checked into the repository.

This file is a large compiled Noir circuit artifact. The ABI correctly marks pk0is and pk1is as private inputs with a public Field return type, consistent with the commitment scheme's hiding property. Based on learnings, pk0is and pk1is in the pk_bfv circuit should remain private inputs because the commitment scheme's hiding property requires these values to stay private.

Consider whether this fixture could be downloaded from the circuit releases (as done for production) or generated at test time to reduce repository size, though acknowledging it's acceptable for test stability.

crates/zk-prover/src/circuits/pkbfv.rs (1)

54-75: Coefficient conversion goes through string round-trip.

Each polynomial coefficient is converted via b.to_string()FieldElement::try_from_str(&s). While this works correctly, it allocates a string per coefficient (up to 2048+ allocations per proof). If FieldElement has a from_be_bytes or similar API, a direct conversion would be more efficient — but this is acceptable for the current use case where proof generation dominates runtime.

crates/zk-prover/tests/local_e2e_tests.rs (2)

24-45: find_bb relies on which, which is not portable.

which is a Unix utility. On non-Unix platforms (or minimal containers), it may not exist. Since the test is already Unix-only (#[cfg(unix)] symlink on Line 61), consider either:

  • Gating the entire test module with #[cfg(unix)], or
  • Using std::process::Command::new("bb").arg("--version") to probe directly instead of which.

This is low-priority since the tests effectively skip on non-Unix platforms anyway.


66-106: Consider extracting the repeated fixture setup into a shared helper.

All three tests duplicate the same pattern: find bb → setup prover → create circuit dir → copy pk.json + pk.vk. A helper like setup_pk_bfv_test() -> Option<(ZkBackend, ZkProver, TempDir)> would reduce ~20 lines of boilerplate per test.

Also applies to: 108-149, 151-213

crates/zk-prover/tests/integration_tests.rs (1)

97-133: Consider adding a #[tokio::test] timeout to prevent indefinite hangs on network failures.

These tests depend on network access. If the remote server is slow or unreachable, the test will hang indefinitely. Tokio's test macro doesn't have a built-in timeout, but you could wrap the body with tokio::time::timeout or use a CI-level timeout.

.github/workflows/ci.yml (1)

392-394: Consider caching the ZK prover artifacts across CI jobs to avoid repeated downloads.

Each job independently runs enclave noir setup, which downloads the BB binary and circuits from GitHub Releases. With multiple jobs running this step, you're making redundant network calls on every CI run. You could cache ~/.enclave/noir/ using actions/cache keyed on the versions.json hash.

Also applies to: 595-597, 802-804

crates/zk-prover/src/actors/proof_request.rs (1)

30-31: Pending map entries have no TTL — orphaned entries will leak if no response or error arrives.

If neither ComputeResponse nor ComputeRequestError is ever received for a given correlation_id (e.g., the multithread actor crashes or the message is lost), the pending HashMap entry persists indefinitely. Over time with repeated failures, this could cause unbounded memory growth.

Consider adding a periodic cleanup or timeout mechanism. This isn't critical for initial release but worth tracking.

Also applies to: 66-73

crates/zk-prover/src/backend/download.rs (2)

104-116: Placeholder version "0.0.0-placeholder" is a good improvement over recording the real version.

This ensures circuits_match() returns false so a retry is triggered on the next setup. However, the save on line 113 still persists version info — consider whether the version file should be left untouched on failure so check_status reports FullSetupNeeded rather than CircuitsNeedUpdate.


164-207: download_with_progress buffers the entire download in memory.

For large circuit archives, this could consume significant memory. Consider streaming to a temporary file instead of accumulating in a Vec<u8>. This is acceptable for now given the likely sizes involved, but worth noting for future scalability.

crates/zk-prover/src/backend/mod.rs (2)

31-38: Consider reducing field visibility.

All fields of ZkBackend are pub. If only specific fields need external access (e.g., bb_binary and circuits_dir for display in CLI), consider exposing them via getters instead. This would prevent external code from mutating paths inconsistently.


69-83: Path traversal guard is good but incomplete.

The sanitization rejects .., /, and \ in e3_id, which covers the most common traversal vectors. However, null bytes (\0) could also be problematic on some systems. Consider also rejecting empty strings.

🛡️ Suggested enhancement
     pub async fn cleanup_work_dir(&self, e3_id: &str) -> Result<(), ZkError> {
         // Sanitize e3_id to prevent path traversal
-        if e3_id.contains("..") || e3_id.contains('/') || e3_id.contains('\\') {
+        if e3_id.is_empty()
+            || e3_id.contains("..")
+            || e3_id.contains('/')
+            || e3_id.contains('\\')
+            || e3_id.contains('\0')
+        {
             return Err(ZkError::IoError(std::io::Error::new(
                 std::io::ErrorKind::InvalidInput,
                 "e3_id contains invalid characters",
             )));
         }
crates/cli/src/noir.rs (1)

12-19: Consider adding Prove and Verify subcommands.

The PR description mentions the CLI should support prove, verify, and help commands, but only Status and Setup are implemented. If those are planned for a future PR, consider adding a comment or TODO here.

crates/events/src/enclave_event/compute_request/mod.rs (2)

71-89: Prefer implementing Display over ToString.

ToString is deprecated in favor of implementing Display (which auto-derives ToString). This is a pre-existing pattern in the file, so not blocking.


121-133: Error messages in try_into_zk/try_into_trbfv hardcode the "other" variant name.

If a third ComputeResponseKind variant is added, these error messages become inaccurate. Consider using {:?} formatting on the variant or a generic "unexpected variant" message.

Minor suggestion
     pub fn try_into_zk(self) -> anyhow::Result<ZkResponse> {
         match self.response {
             ComputeResponseKind::Zk(zk) => Ok(zk),
-            _ => bail!("Expected ZkResponse but got TrBFV"),
+            other => bail!("Expected ZkResponse but got {:?}", std::mem::discriminant(&other)),
         }
     }
crates/zk-prover/src/config.rs (2)

200-220: verify_checksum silently passes when no expected checksum is provided.

This is correct behavior for optional checksums, but combined with the fail-open fetch_or_default, it creates a chain where network failure → empty checksums → all verification skipped. Ensure at least the download_bb path always has checksums available (e.g., embedded defaults).


96-119: fetch_latest creates a new reqwest::Client per call.

If fetch_latest or fetch_or_default is called frequently, consider reusing a client. For a one-shot config fetch this is fine, but worth noting if usage patterns change.

crates/keyshare/src/threshold_keyshare.rs (4)

404-418: Catch-all arm silently swallows unknown TrBFVResponse variants.

Line 415's _ => Ok(()) means any new TrBFVResponse variant added in the future will be silently ignored here without a compiler warning. Consider logging a warning for unrecognised variants to aid debugging.

💡 Suggested improvement
-                _ => Ok(()),
+                other => {
+                    warn!("Unhandled TrBFVResponse variant: {:?}", other);
+                    Ok(())
+                }

428-430: Silently discarding Result from collector setup.

Both ensure_collector and ensure_encryption_key_collector return Result, and the errors are discarded with let _ =. If self.state.get() returns None at this point, the collectors won't be created and no diagnostic will be emitted. Since these are retried lazily later, this isn't a functional bug, but at minimum a warn! on failure would help diagnose startup ordering issues.

💡 Suggested improvement
-        let _ = self.ensure_collector(address.clone());
-        let _ = self.ensure_encryption_key_collector(address.clone());
+        if let Err(e) = self.ensure_collector(address.clone()) {
+            warn!("Early collector setup failed (will retry): {e}");
+        }
+        if let Err(e) = self.ensure_encryption_key_collector(address.clone()) {
+            warn!("Early encryption key collector setup failed (will retry): {e}");
+        }

432-432: Repeated BfvParamSet::from(self.share_enc_preset…).build_arc() in three places.

Lines 432, 684, and 760 all perform the same preset-to-params conversion. A small helper on ThresholdKeyshare (e.g., fn share_enc_params(&self) -> Arc<BfvParameters>) would eliminate the duplication and make future changes to the conversion a single-point edit.

Also applies to: 684-684, 760-760


441-458: State snapshot used after mutation — works correctly but is subtle.

state is captured at line 441 (before the mutation at line 444), then state.party_id is read at line 456 to construct the published event. This is safe because party_id lives on the outer ThresholdKeyshareState and is invariant across transitions, but it's easy to misread as a stale-state bug. A brief inline comment would help future readers.

Comment thread crates/ciphernode-builder/src/ciphernode_builder.rs
Comment thread crates/cli/src/noir.rs
Comment thread crates/multithread/src/multithread.rs Outdated
Comment thread crates/zk-prover/src/actors/proof_request.rs
Comment thread crates/zk-prover/src/backend/mod.rs Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@crates/config/src/paths_engine.rs`:
- Around line 173-182: The fallback in get_enclave_dir currently builds the path
from default_data_dir.parent().join(".enclave"), which yields
~/.local/share/.enclave instead of the intended ~/.enclave; update
get_enclave_dir to use the user home directory (e.g. dirs::home_dir() or
dirs_next::home_dir()) and join(".enclave") when get_root_dir() is None,
ensuring you still handle None from home_dir() (fall back to default_data_dir as
last resort), or alternatively update the doc comment to explicitly state that
default_data_dir.parent().join(".enclave") is intended; refer to
get_enclave_dir, default_data_dir and OsDirs::data_dir() when making the change.
🧹 Nitpick comments (3)
crates/zk-prover/src/backend/mod.rs (2)

61-77: with_default_dir duplicates path layout already defined in PathsEngine.

PathsEngine (in crates/config/src/paths_engine.rs, lines 184-201) already centralizes the ~/.enclave/noir/ directory structure (noir_dir, bb_binary, circuits_dir, work_dir). Hardcoding the same ".enclave"/"noir"/"bin"/"bb" etc. here means two places must be kept in sync.

The entrypoint in start.rs already uses AppConfig paths (e.g., config.bb_binary()), so with_default_dir appears to be a convenience for CLI/test paths that don't have an AppConfig. Consider delegating to PathsEngine to avoid divergence.


47-49: expect() in a public constructor can panic on pathological input.

If circuits_dir has no parent (e.g., a bare filename or root path), this panics. Since ZkBackend::new is a public API called with external config, returning Result (or defaulting) would be safer.

Proposed handling
-        let base_dir = circuits_dir
-            .parent()
-            .expect("circuits_dir should have a parent")
-            .to_path_buf();
+        let base_dir = circuits_dir
+            .parent()
+            .unwrap_or(&circuits_dir)
+            .to_path_buf();

Or change the signature to return Result<Self, ZkError>.

crates/config/src/paths_engine.rs (1)

184-202: No test coverage for the new path accessors.

The existing test infrastructure (TestCase / PathsExpected) validates config_file, key_file, db_file, and log_file, but the new noir_dir, bb_binary, circuits_dir, and work_dir methods have no test coverage. Given the nuanced fallback logic in get_enclave_dir, at least two cases should be tested: (1) with a found_config_file (project-local) and (2) without (global fallback).

Comment thread crates/config/src/paths_engine.rs Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@crates/cli/src/noir.rs`:
- Around line 74-106: Status output currently displays only the single
SetupStatus returned by check_status(), so if both Barretenberg and circuits
need updates the user only sees one; update the logic to report both checks by
either changing check_status() to return a composite result (e.g., a struct or
bitflags) or by calling the individual check functions for Barretenberg and
circuits from the status command and printing both results; ensure you reference
and adjust the SetupStatus enum handling in the status display code (the match
on SetupStatus in noir.rs) so it can emit combined messages like "Barretenberg
needs update" and "Circuits need update" together, and keep the existing prompts
to run `enclave noir setup`.
- Around line 21-28: The execute function currently ignores AppConfig and always
initializes ZkBackend via ZkBackend::with_default_dir("test_node"), causing
hardcoded work paths; change execute to build the ZkBackend using values
resolved from the provided &AppConfig (use its PathsEngine-resolved node name
and paths such as bb_binary, circuits_dir and work_dir) and pass that backend
into the same logic instead of calling execute_without_config; keep
execute_without_config as a true no-config fallback (or at least replace the
literal "test_node" with a documented dev-only default) so callers with a config
get a backend constructed from AppConfig rather than the hardcoded path.

In `@crates/zk-prover/src/backend/mod.rs`:
- Around line 79-88: sanitize_e3_id currently allows empty strings and null
bytes which can lead to joining the root work_dir (deleting everything) or
truncation; update sanitize_e3_id to reject empty e3_id and any embedded NUL
characters: return Err(ZkError::IoError(...InvalidInput...)) if e3_id.is_empty()
or e3_id.contains('\0'), in addition to the existing checks for "..", '/' and
'\\' so cleanup_work_dir / work_dir.join(e3_id) cannot be passed an empty or
NUL-containing identifier.
🧹 Nitpick comments (7)
crates/zk-prover/src/backend/mod.rs (1)

46-50: expect() in a public constructor can panic on edge-case input.

circuits_dir.parent() returns None for root paths (e.g., /) or relative paths with a single component. Since new is public, a misconfigured caller could trigger this panic at runtime.

Proposed fix — return `Result` or default gracefully

If changing new to return Result is too disruptive, at minimum guard against the edge case:

-        let base_dir = circuits_dir
-            .parent()
-            .expect("circuits_dir should have a parent")
-            .to_path_buf();
+        let base_dir = circuits_dir
+            .parent()
+            .unwrap_or(&circuits_dir)
+            .to_path_buf();
crates/zk-prover/src/prover.rs (1)

39-123: All I/O and subprocess calls in generate_proof/verify_proof are blocking.

std::fs::* and std::process::Command block the calling thread. If these methods are invoked on a Tokio runtime (the tests use #[tokio::test]), they'll block the async executor. Consider using tokio::task::spawn_blocking at the call sites, or switching to tokio::fs and tokio::process::Command internally.

Also applies to: 129-194

crates/zk-prover/tests/local_e2e_tests.rs (2)

86-96: Fixture copy block is duplicated three times — consider a helper.

The circuit_dir creation + pk.json / pk.vk copy sequence is identical across all three tests. Extracting it would reduce maintenance and make adding new test fixtures simpler.

♻️ Sketch
async fn copy_pk_fixtures(backend: &ZkBackend, fixtures: &std::path::Path) {
    let circuit_dir = backend.circuits_dir.join("dkg").join("pk");
    fs::create_dir_all(&circuit_dir).await.unwrap();
    fs::copy(fixtures.join("pk.json"), circuit_dir.join("pk.json"))
        .await
        .unwrap();
    fs::copy(fixtures.join("pk.vk"), circuit_dir.join("pk.vk"))
        .await
        .unwrap();
}

Also applies to: 128-138, 171-181


47-47: Nit: prefer &Path over &PathBuf in function signatures.

Idiomatic Rust: &Path is the borrowed form of PathBuf, analogous to &str vs &String. &PathBuf auto-derefs but needlessly restricts the caller.

-async fn setup_test_prover(bb: &PathBuf) -> (ZkBackend, tempfile::TempDir) {
+async fn setup_test_prover(bb: &std::path::Path) -> (ZkBackend, tempfile::TempDir) {
crates/config/src/paths_engine.rs (1)

180-198: No test coverage for the new noir path methods.

The existing test suite validates config_file, key_file, db_file, and log_file, but none of the new noir_dir, bb_binary, circuits_dir, or work_dir methods are tested. Consider extending the TestCase / PathsExpected struct to cover these paths, especially given the fallback logic in get_noir_base.

crates/multithread/src/multithread.rs (1)

337-353: No validation that req.params_preset is a DKG preset.

The comment on line 342 states the expectation but doesn't enforce it. If a threshold preset (e.g., InsecureThreshold512) is passed, PublicKey::from_bytes would attempt deserialization with threshold parameters (which may succeed or produce garbage), and threshold_counterpart() would return None, triggering the silent fallback. Consider adding a guard.

Proposed guard
+    if req.params_preset.threshold_counterpart().is_none() {
+        return Err(ComputeRequestError::new(
+            ComputeRequestErrorKind::Zk(ZkEventError::InvalidParams(format!(
+                "Expected a DKG preset, got {:?}",
+                req.params_preset
+            ))),
+            request.clone(),
+        ));
+    }
+
     // NOTE: req.params_preset is expected to contain a DKG preset (e.g., InsecureDkg512)
crates/cli/src/noir.rs (1)

7-7: Prefer explicit imports over glob import.

use anyhow::* pulls in everything from anyhow. The file only needs Result and anyhow!.

Proposed fix
-use anyhow::*;
+use anyhow::{anyhow, Result};

Comment thread crates/cli/src/noir.rs Outdated
Comment thread crates/cli/src/noir.rs
Comment thread crates/zk-prover/src/backend/mod.rs Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@crates/cli/src/noir.rs`:
- Around line 128-156: The force branch in execute_setup calls
backend.download_bb() and backend.download_circuits() without creating the
required directories that ensure_installed() would create, causing unpack
failures; fix by either invoking backend.ensure_installed().await at the start
of the force path (bypassing the prior status check) or explicitly calling
fs::create_dir_all() for the same directories ensure_installed() creates (e.g.,
base_dir, bin, circuits_dir, work_dir) before calling download_bb() and
download_circuits(); update map_err messages as needed and keep the rest of
execute_setup logic unchanged.
🧹 Nitpick comments (2)
crates/cli/src/noir.rs (2)

42-57: Consider adding a doc comment clarifying this is a dev/test fallback.

The "default" string is an improvement over the previous "test_node", but callers have no visibility into when this path is used or what directory it resolves to. A brief /// doc comment explaining this is the no-config fallback (and what work directory it maps to) would help maintainability.


134-155: Prefer .context() over .map_err(|e| anyhow!(…)) for idiomatic error chaining.

The current .map_err(|e| anyhow!("Failed to download bb: {}", e)) pattern stringifies the underlying error, losing the causal chain. Using .context("Failed to download bb") (from anyhow::Context) preserves the original error as a cause, which aids debugging.

Proposed diff
+use anyhow::Context;
+
 // In execute_setup:
         backend
             .download_bb()
             .await
-            .map_err(|e| anyhow!("Failed to download bb: {}", e))?;
+            .context("Failed to download bb")?;
         backend
             .download_circuits()
             .await
-            .map_err(|e| anyhow!("Failed to download circuits: {}", e))?;
+            .context("Failed to download circuits")?;
     } else {
         // ...
         backend
             .ensure_installed()
             .await
-            .map_err(|e| anyhow!("Setup failed: {}", e))?;
+            .context("Setup failed")?;

The same applies to line 45 in execute_without_config.

Comment thread crates/cli/src/noir.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@crates/zk-prover/src/config.rs`:
- Line 20: BB_VERSION in config.rs is set to a nightly pre-release
("3.0.0-nightly..."); change the constant BB_VERSION to a tagged stable
Barretenberg release string (e.g., "3.0.0" or the current official stable tag)
to avoid using nightly builds; update the BB_VERSION constant in config.rs (and
any build/packaging metadata that references it) so the project pins to that
stable tag.
- Around line 194-197: The current verify_circuit_checksum in
verify_circuit_checksum silently skips verification when the circuit name is
missing because expected is None; change it to explicitly check
self.circuits.get(circuit_name) and return an Err(ZkError::...) (e.g., a new or
existing CircuitNotFound/ManifestError variant) if the circuit entry is absent,
otherwise pass the found checksum string to verify_checksum as before
(reference: verify_circuit_checksum, self.circuits, verify_checksum).
- Around line 401-534: Mark the two network-heavy integration tests
test_download_and_verify_bb and test_download_checksum_mismatch_on_corruption so
they don't run by default: either add the #[ignore] attribute above each test
function (so they run only with cargo test -- --ignored) or gate them behind a
feature (e.g., #[cfg(feature = "download_tests")] plus enabling that feature in
CI when needed). Update the test annotations accordingly and, if using a feature
gate, document the feature in Cargo.toml so callers can enable it.
🧹 Nitpick comments (1)
crates/zk-prover/src/config.rs (1)

490-534: Corruption test downloads the full binary just to flip one byte — consider using synthetic data.

test_download_checksum_mismatch_on_corruption re-downloads the entire tarball only to corrupt it and verify the mismatch path. This test doesn't validate anything about the real binary; it only exercises verify_bb_checksum with non-matching data. A unit test with a small synthetic byte array would be equivalent, faster, and deterministic.

Suggested replacement
-    #[tokio::test]
-    async fn test_download_checksum_mismatch_on_corruption() {
-        let Some(target) = BbTarget::current() else {
-            println!("skipping test: unsupported platform");
-            return;
-        };
-
-        let version = BB_VERSION;
-        let (arch, os) = target.url_parts();
-        let url = format!(
-            "https://github.com/AztecProtocol/aztec-packages/releases/download/v{version}/barretenberg-{arch}-{os}.tar.gz"
-        );
-
-        let client = reqwest::Client::new();
-        let response = client
-            .get(&url)
-            .timeout(Duration::from_secs(120))
-            .send()
-            .await
-            .expect("failed to send request");
-
-        let mut bytes = response
-            .bytes()
-            .await
-            .expect("failed to read body")
-            .to_vec();
-
-        // Corrupt the data
-        if !bytes.is_empty() {
-            bytes[0] ^= 0xFF;
-        }
-
-        // Use a valid checksum that won't match corrupted data
-        let info = VersionInfo {
-            bb_checksum: Some(
-                "a56257d8edc226180f5a7093393e4adc99447368a65099bb34292bd261408b99".to_string(),
-            ),
-            ..Default::default()
-        };
-
-        let result = info.verify_bb_checksum(&bytes);
-        assert!(matches!(result, Err(ZkError::ChecksumMismatch { .. })));
-        println!("correctly detected corrupted download");
-    }
+    #[test]
+    fn test_verify_bb_checksum_mismatch_on_corruption() {
+        let data = b"some arbitrary binary payload";
+        // Checksum that does NOT match the data above
+        let info = VersionInfo {
+            bb_checksum: Some(
+                "0000000000000000000000000000000000000000000000000000000000000000".to_string(),
+            ),
+            ..Default::default()
+        };
+
+        let result = info.verify_bb_checksum(data);
+        assert!(matches!(result, Err(ZkError::ChecksumMismatch { .. })));
+    }

Comment thread crates/zk-prover/src/config.rs
Comment thread crates/zk-prover/src/config.rs
Comment thread crates/zk-prover/src/config.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@crates/zk-prover/src/config.rs`:
- Around line 409-466: The test uses BB_VERSION to download barretenberg but the
hard-coded checksums map (called checksums) is for an older v0.82.2, causing
verify_checksum (and the test_download_and_verify_bb) to always fail; fix by
either updating the checksums map entries to the correct SHA256 values for the
current BB_VERSION ("3.0.0-nightly.20251104") for each target key (amd64-linux,
amd64-darwin, arm64-linux, arm64-darwin), or change the test to derive the
download version from the checksums source (or a checksum file) instead of
BB_VERSION so the url/version and the checksums stay in sync — update the
checksums variable or the version assignment (version / url) and re-run
verify_checksum to ensure they match.

In `@crates/zk-prover/src/prover.rs`:
- Around line 69-75: The output directory (output_dir) is not created before
being passed to the bb prove -o flag; update the code that builds
job_dir/output_dir (the block creating job_dir, witness_path, and output_dir) to
call fs::create_dir_all(&output_dir) (or replace the existing
fs::create_dir_all(&job_dir) with fs::create_dir_all(&output_dir)) so the out
directory exists prior to running bb prove, matching the verify_proof pattern
and ensuring subsequent reads of proof and public_inputs succeed.
🧹 Nitpick comments (3)
crates/zk-prover/src/config.rs (1)

176-179: Non-atomic file write risks partial/corrupt state on crash.

save() writes directly to the target path. If the process is interrupted mid-write, version.json could end up truncated or empty. Consider writing to a temporary file in the same directory, then renaming atomically.

♻️ Suggested approach
     pub async fn save(&self, path: &Path) -> std::io::Result<()> {
         let contents = serde_json::to_string_pretty(self)?;
-        fs::write(path, contents).await
+        let tmp = path.with_extension("tmp");
+        fs::write(&tmp, contents).await?;
+        fs::rename(&tmp, path).await
     }
crates/zk-prover/src/prover.rs (2)

152-170: Verification artifacts are left on disk after verify_proof completes.

The verify_{verification_id} subdirectory (proof file, public_inputs) persists after verification finishes. Since cleanup(e3_id) removes the entire e3_id directory, these files will only be cleaned up if cleanup is explicitly called later. Consider removing the per-verification subdirectory at the end of verify_proof (in a finally-style block or explicit cleanup), especially since the written data is already held in memory.


224-237: Test coverage is minimal — only the BbNotInstalled path is exercised.

The PR description already notes E2E tests are a remaining task. Consider adding unit tests for the error paths that don't require a real bb binary — e.g., CircuitNotFound when circuit/VK files are missing (create the bb_binary file but not the circuit files).

Comment thread crates/zk-prover/src/config.rs
Comment thread crates/zk-prover/src/prover.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@crates/zk-prover/src/actors/zk_actor.rs`:
- Around line 84-85: The current send call msg.sender.do_send(response) can
silently drop the message; replace it with msg.sender.try_send(response) and
handle the Result: on Err, log the failure (include the response details and the
error) and take appropriate recovery (retry, escalate, or mark the verification
as failed) so the verification path cannot silently stall; alternatively, if you
move this code to async, use msg.sender.send(response).await and similarly
handle/log the error case.
- Around line 32-34: The Actor impl for ZkActor currently uses the default
Context and runs blocking work (verify_proof invoking bb and filesystem I/O) on
the arbiter thread; change the actor to use a blocking-friendly context or
offload blocking I/O: either switch the actor context to actix::SyncContext by
updating impl Actor for ZkActor { type Context = actix::SyncContext<Self>; } and
start instances with SyncArbiter::start(...) so verify_proof runs on worker
threads, or keep the current Context and modify the handler that calls
verify_proof to run the subprocess/filesystem operations inside a
tokio::task::spawn_blocking (or equivalent) so the blocking work does not run on
the arbiter thread. Ensure references to ZkActor and the verify_proof callsite
are updated accordingly.

In `@crates/zk-prover/src/prover.rs`:
- Around line 83-97: The subprocess calls using StdCommand::output() in the
prove routine (invoking self.bb_binary with "prove") — and the similar call in
verify_proof (the "bb verify" invocation) — lack a timeout and can block
indefinitely; change both to spawn the child (StdCommand::spawn()), monitor with
a timeout (e.g., wait-timeout crate or std/tokio timeout), and if the timeout
elapses kill the child, collect/return its stderr/stdout as part of an Err
variant so callers see why it timed out; ensure you use the same bb_binary,
circuit_path/witness_path/vk_path/output_dir arguments as before and surface a
descriptive error from the prove and verify_proof functions when the process is
killed for exceeding the timeout.
🧹 Nitpick comments (2)
crates/zk-prover/src/traits.rs (1)

29-49: Cache self.circuit() in a local variable to avoid repeated calls.

self.circuit() is invoked three times (lines 38, 41, 48). Storing it once improves readability and avoids any subtle inconsistency risk.

♻️ Proposed refactor
     fn prove(
         &self,
         prover: &ZkProver,
         params: &Self::Params,
         input: &Self::Input,
         e3_id: &str,
     ) -> Result<Proof, ZkError> {
         let inputs = self.build_witness(params, input)?;
 
-        let circuit_name = self.circuit().as_str();
+        let circuit = self.circuit();
+        let circuit_name = circuit.as_str();
         let circuit_path = prover
             .circuits_dir()
-            .join(self.circuit().dir_path())
+            .join(circuit.dir_path())
             .join(format!("{}.json", circuit_name));
-        let circuit = CompiledCircuit::from_file(&circuit_path)?;
+        let compiled = CompiledCircuit::from_file(&circuit_path)?;
 
         let witness_gen = WitnessGenerator::new();
-        let witness = witness_gen.generate_witness(&circuit, inputs)?;
+        let witness = witness_gen.generate_witness(&compiled, inputs)?;
 
-        prover.generate_proof(self.circuit(), &witness, e3_id)
+        prover.generate_proof(circuit, &witness, e3_id)
     }
crates/zk-prover/src/prover.rs (1)

31-37: Nit: return &Path instead of &PathBuf from accessors.

Idiomatic Rust accessors for PathBuf fields return &Path, since callers rarely need the owned-buffer methods. &PathBuf coerces to &Path at call sites, so this is source-compatible if changed now but gets harder to change later once there are more consumers.

♻️ Suggested diff
+use std::path::{Path, PathBuf};
-use std::path::PathBuf;

-    pub fn circuits_dir(&self) -> &PathBuf {
+    pub fn circuits_dir(&self) -> &Path {
         &self.circuits_dir
     }

-    pub fn work_dir(&self) -> &PathBuf {
+    pub fn work_dir(&self) -> &Path {
         &self.work_dir
     }

Comment thread crates/zk-prover/src/actors/zk_actor.rs
Comment thread crates/zk-prover/src/actors/zk_actor.rs
Comment thread crates/zk-prover/src/prover.rs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants